From ff6c3eadad8bb82eff7390f94ef30ac079ce1fd5 Mon Sep 17 00:00:00 2001 From: stainless-bot Date: Wed, 20 Nov 2024 19:10:29 +0000 Subject: [PATCH] feat(api): update via SDK Studio --- .stats.yml | 4 +- api.md | 136 +- src/cloudflare/_client.py | 74 + src/cloudflare/resources/filters.py | 940 +++++++++++++ src/cloudflare/resources/firewall/__init__.py | 42 + .../resources/firewall/access_rules.py | 518 ++++++- src/cloudflare/resources/firewall/firewall.py | 96 ++ .../resources/firewall/lockdowns.py | 754 ++++++++++ src/cloudflare/resources/firewall/rules.py | 1210 ++++++++++++++++ src/cloudflare/resources/firewall/ua_rules.py | 717 ++++++++++ .../resources/firewall/waf/__init__.py | 14 + .../resources/firewall/waf/overrides.py | 706 ++++++++++ .../firewall/waf/packages/packages.py | 285 ++++ src/cloudflare/resources/firewall/waf/waf.py | 32 + .../resources/{pagerules => }/pagerules.py | 242 +--- .../resources/pagerules/__init__.py | 33 - .../resources/pagerules/settings.py | 180 --- src/cloudflare/resources/rate_limits.py | 778 +++++++++++ src/cloudflare/types/filters/__init__.py | 9 + .../filters/filter_bulk_delete_response.py | 10 + .../filters/filter_bulk_update_response.py | 10 + .../types/filters/filter_create_params.py | 19 + .../types/filters/filter_create_response.py | 10 + .../types/filters/filter_list_params.py | 33 + .../types/filters/filter_update_params.py | 14 + .../types/filters/firewall_filter.py | 28 + .../types/filters/firewall_filter_param.py | 25 + src/cloudflare/types/firewall/__init__.py | 42 + .../access_rule_cidr_configuration.py | 24 + .../firewall/access_rule_create_response.py | 57 +- .../firewall/access_rule_delete_response.py | 11 + .../types/firewall/access_rule_edit_params.py | 42 + .../firewall/access_rule_edit_response.py | 57 + .../firewall/access_rule_get_response.py | 57 + .../firewall/access_rule_ip_configuration.py | 22 + .../firewall/access_rule_list_response.py | 57 + .../types/firewall/asn_configuration.py | 20 + .../types/firewall/configuration.py | 13 + .../types/firewall/configuration_param.py | 15 + .../types/firewall/country_configuration.py | 23 + .../types/firewall/deleted_filter.py | 14 + .../types/firewall/firewall_rule.py | 46 + .../types/firewall/ipv6_configuration.py | 19 + src/cloudflare/types/firewall/lockdown.py | 41 + .../firewall/lockdown_cidr_configuration.py | 20 + .../lockdown_cidr_configuration_param.py | 19 + .../types/firewall/lockdown_create_params.py | 30 + .../firewall/lockdown_delete_response.py | 12 + .../firewall/lockdown_ip_configuration.py | 23 + .../lockdown_ip_configuration_param.py | 22 + .../types/firewall/lockdown_list_params.py | 57 + .../types/firewall/lockdown_update_params.py | 30 + .../firewall/rule_bulk_delete_response.py | 10 + .../types/firewall/rule_bulk_edit_params.py | 14 + .../types/firewall/rule_bulk_edit_response.py | 10 + .../types/firewall/rule_bulk_update_params.py | 14 + .../firewall/rule_bulk_update_response.py | 10 + .../types/firewall/rule_create_params.py | 59 + .../types/firewall/rule_create_response.py | 10 + .../rule_edit_response.py} | 6 +- .../types/firewall/rule_get_params.py | 15 + .../types/firewall/rule_list_params.py | 30 + .../types/firewall/rule_update_params.py | 59 + .../types/firewall/ua_rule_create_params.py | 34 + .../types/firewall/ua_rule_create_response.py | 8 + .../types/firewall/ua_rule_delete_response.py | 12 + .../types/firewall/ua_rule_get_response.py | 8 + .../types/firewall/ua_rule_list_params.py | 31 + .../types/firewall/ua_rule_list_response.py | 39 + .../types/firewall/ua_rule_update_params.py | 34 + .../types/firewall/ua_rule_update_response.py | 8 + src/cloudflare/types/firewall/waf/__init__.py | 11 + src/cloudflare/types/firewall/waf/override.py | 59 + .../firewall/waf/override_create_params.py | 22 + .../firewall/waf/override_delete_response.py | 12 + .../firewall/waf/override_list_params.py | 18 + .../firewall/waf/override_update_params.py | 42 + .../firewall/waf/package_get_response.py | 27 + .../types/firewall/waf/package_list_params.py | 33 + .../types/firewall/waf/rewrite_action.py | 25 + .../firewall/waf/rewrite_action_param.py | 24 + src/cloudflare/types/firewall/waf/waf_rule.py | 8 + .../types/firewall/waf/waf_rule_param.py | 10 + src/cloudflare/types/pagerules/__init__.py | 1 - src/cloudflare/types/pagerules/page_rule.py | 344 ++++- .../types/pagerules/pagerule_create_params.py | 340 ++++- .../types/pagerules/pagerule_edit_params.py | 340 ++++- .../types/pagerules/pagerule_update_params.py | 340 ++++- src/cloudflare/types/rate_limits/__init__.py | 5 + .../types/rate_limits/rate_limit.py | 150 ++ .../rate_limits/rate_limit_create_params.py | 129 ++ .../rate_limits/rate_limit_delete_response.py | 159 +++ .../rate_limits/rate_limit_edit_params.py | 129 ++ .../rate_limits/rate_limit_list_params.py | 22 + src/cloudflare/types/zones/__init__.py | 21 + .../types/zones/always_use_https.py | 16 +- .../types/zones/always_use_https_param.py | 15 + .../types/zones/automatic_https_rewrites.py | 16 +- .../zones/automatic_https_rewrites_param.py | 11 + .../types/zones/browser_cache_ttl.py | 46 +- .../types/zones/browser_cache_ttl_param.py | 18 + src/cloudflare/types/zones/browser_check.py | 17 +- .../types/zones/browser_check_param.py | 18 + src/cloudflare/types/zones/cache_level.py | 23 +- .../types/zones/cache_level_param.py | 24 + .../types/zones/development_mode.py | 23 +- .../types/zones/development_mode_param.py | 11 + .../types/zones/email_obfuscation.py | 18 +- .../types/zones/email_obfuscation_param.py | 15 + .../types/zones/hotlink_protection.py | 16 +- .../types/zones/hotlink_protection_param.py | 11 + src/cloudflare/types/zones/ip_geolocation.py | 21 +- .../types/zones/ip_geolocation_param.py | 22 + src/cloudflare/types/zones/mirage.py | 22 +- src/cloudflare/types/zones/mirage_param.py | 23 + .../types/zones/opportunistic_encryption.py | 22 +- .../zones/opportunistic_encryption_param.py | 23 + .../zones/origin_error_page_pass_thru.py | 21 +- .../origin_error_page_pass_thru_param.py | 22 + src/cloudflare/types/zones/polish.py | 22 +- src/cloudflare/types/zones/polish_param.py | 19 + .../types/zones/response_buffering.py | 18 +- .../types/zones/response_buffering_param.py | 19 + src/cloudflare/types/zones/rocket_loader.py | 18 +- .../types/zones/rocket_loader_param.py | 15 + src/cloudflare/types/zones/security_level.py | 17 +- .../types/zones/security_level_param.py | 14 + .../types/zones/server_side_excludes.py | 16 +- .../types/zones/server_side_excludes_param.py | 11 + .../types/zones/setting_edit_params.py | 132 +- .../types/zones/setting_edit_response.py | 483 ++++++- .../types/zones/setting_get_response.py | 483 ++++++- .../zones/sort_query_string_for_cache.py | 23 +- .../sort_query_string_for_cache_param.py | 22 + src/cloudflare/types/zones/ssl.py | 21 +- src/cloudflare/types/zones/ssl_param.py | 22 + .../types/zones/true_client_ip_header.py | 22 +- .../zones/true_client_ip_header_param.py | 19 + src/cloudflare/types/zones/waf.py | 22 +- src/cloudflare/types/zones/waf_param.py | 23 + .../firewall/test_access_rules.py | 464 ++++++- .../api_resources/firewall/test_lockdowns.py | 555 ++++++++ tests/api_resources/firewall/test_rules.py | 1112 +++++++++++++++ tests/api_resources/firewall/test_ua_rules.py | 599 ++++++++ .../firewall/waf/test_overrides.py | 586 ++++++++ .../firewall/waf/test_packages.py | 231 ++++ tests/api_resources/pagerules/__init__.py | 1 - .../api_resources/pagerules/test_settings.py | 98 -- tests/api_resources/test_filters.py | 758 ++++++++++ tests/api_resources/test_pagerules.py | 1218 ++++++++--------- tests/api_resources/test_rate_limits.py | 770 +++++++++++ 151 files changed, 16946 insertions(+), 1735 deletions(-) create mode 100644 src/cloudflare/resources/filters.py create mode 100644 src/cloudflare/resources/firewall/lockdowns.py create mode 100644 src/cloudflare/resources/firewall/rules.py create mode 100644 src/cloudflare/resources/firewall/ua_rules.py create mode 100644 src/cloudflare/resources/firewall/waf/overrides.py rename src/cloudflare/resources/{pagerules => }/pagerules.py (78%) delete mode 100644 src/cloudflare/resources/pagerules/__init__.py delete mode 100644 src/cloudflare/resources/pagerules/settings.py create mode 100644 src/cloudflare/resources/rate_limits.py create mode 100644 src/cloudflare/types/filters/filter_bulk_delete_response.py create mode 100644 src/cloudflare/types/filters/filter_bulk_update_response.py create mode 100644 src/cloudflare/types/filters/filter_create_params.py create mode 100644 src/cloudflare/types/filters/filter_create_response.py create mode 100644 src/cloudflare/types/filters/filter_list_params.py create mode 100644 src/cloudflare/types/filters/filter_update_params.py create mode 100644 src/cloudflare/types/filters/firewall_filter.py create mode 100644 src/cloudflare/types/filters/firewall_filter_param.py create mode 100644 src/cloudflare/types/firewall/access_rule_cidr_configuration.py create mode 100644 src/cloudflare/types/firewall/access_rule_delete_response.py create mode 100644 src/cloudflare/types/firewall/access_rule_edit_params.py create mode 100644 src/cloudflare/types/firewall/access_rule_edit_response.py create mode 100644 src/cloudflare/types/firewall/access_rule_get_response.py create mode 100644 src/cloudflare/types/firewall/access_rule_ip_configuration.py create mode 100644 src/cloudflare/types/firewall/access_rule_list_response.py create mode 100644 src/cloudflare/types/firewall/asn_configuration.py create mode 100644 src/cloudflare/types/firewall/configuration.py create mode 100644 src/cloudflare/types/firewall/configuration_param.py create mode 100644 src/cloudflare/types/firewall/country_configuration.py create mode 100644 src/cloudflare/types/firewall/deleted_filter.py create mode 100644 src/cloudflare/types/firewall/firewall_rule.py create mode 100644 src/cloudflare/types/firewall/ipv6_configuration.py create mode 100644 src/cloudflare/types/firewall/lockdown.py create mode 100644 src/cloudflare/types/firewall/lockdown_cidr_configuration.py create mode 100644 src/cloudflare/types/firewall/lockdown_cidr_configuration_param.py create mode 100644 src/cloudflare/types/firewall/lockdown_create_params.py create mode 100644 src/cloudflare/types/firewall/lockdown_delete_response.py create mode 100644 src/cloudflare/types/firewall/lockdown_ip_configuration.py create mode 100644 src/cloudflare/types/firewall/lockdown_ip_configuration_param.py create mode 100644 src/cloudflare/types/firewall/lockdown_list_params.py create mode 100644 src/cloudflare/types/firewall/lockdown_update_params.py create mode 100644 src/cloudflare/types/firewall/rule_bulk_delete_response.py create mode 100644 src/cloudflare/types/firewall/rule_bulk_edit_params.py create mode 100644 src/cloudflare/types/firewall/rule_bulk_edit_response.py create mode 100644 src/cloudflare/types/firewall/rule_bulk_update_params.py create mode 100644 src/cloudflare/types/firewall/rule_bulk_update_response.py create mode 100644 src/cloudflare/types/firewall/rule_create_params.py create mode 100644 src/cloudflare/types/firewall/rule_create_response.py rename src/cloudflare/types/{pagerules/setting_list_response.py => firewall/rule_edit_response.py} (55%) create mode 100644 src/cloudflare/types/firewall/rule_get_params.py create mode 100644 src/cloudflare/types/firewall/rule_list_params.py create mode 100644 src/cloudflare/types/firewall/rule_update_params.py create mode 100644 src/cloudflare/types/firewall/ua_rule_create_params.py create mode 100644 src/cloudflare/types/firewall/ua_rule_create_response.py create mode 100644 src/cloudflare/types/firewall/ua_rule_delete_response.py create mode 100644 src/cloudflare/types/firewall/ua_rule_get_response.py create mode 100644 src/cloudflare/types/firewall/ua_rule_list_params.py create mode 100644 src/cloudflare/types/firewall/ua_rule_list_response.py create mode 100644 src/cloudflare/types/firewall/ua_rule_update_params.py create mode 100644 src/cloudflare/types/firewall/ua_rule_update_response.py create mode 100644 src/cloudflare/types/firewall/waf/override.py create mode 100644 src/cloudflare/types/firewall/waf/override_create_params.py create mode 100644 src/cloudflare/types/firewall/waf/override_delete_response.py create mode 100644 src/cloudflare/types/firewall/waf/override_list_params.py create mode 100644 src/cloudflare/types/firewall/waf/override_update_params.py create mode 100644 src/cloudflare/types/firewall/waf/package_get_response.py create mode 100644 src/cloudflare/types/firewall/waf/package_list_params.py create mode 100644 src/cloudflare/types/firewall/waf/rewrite_action.py create mode 100644 src/cloudflare/types/firewall/waf/rewrite_action_param.py create mode 100644 src/cloudflare/types/firewall/waf/waf_rule.py create mode 100644 src/cloudflare/types/firewall/waf/waf_rule_param.py create mode 100644 src/cloudflare/types/rate_limits/rate_limit.py create mode 100644 src/cloudflare/types/rate_limits/rate_limit_create_params.py create mode 100644 src/cloudflare/types/rate_limits/rate_limit_delete_response.py create mode 100644 src/cloudflare/types/rate_limits/rate_limit_edit_params.py create mode 100644 src/cloudflare/types/rate_limits/rate_limit_list_params.py create mode 100644 src/cloudflare/types/zones/always_use_https_param.py create mode 100644 src/cloudflare/types/zones/automatic_https_rewrites_param.py create mode 100644 src/cloudflare/types/zones/browser_cache_ttl_param.py create mode 100644 src/cloudflare/types/zones/browser_check_param.py create mode 100644 src/cloudflare/types/zones/cache_level_param.py create mode 100644 src/cloudflare/types/zones/development_mode_param.py create mode 100644 src/cloudflare/types/zones/email_obfuscation_param.py create mode 100644 src/cloudflare/types/zones/hotlink_protection_param.py create mode 100644 src/cloudflare/types/zones/ip_geolocation_param.py create mode 100644 src/cloudflare/types/zones/mirage_param.py create mode 100644 src/cloudflare/types/zones/opportunistic_encryption_param.py create mode 100644 src/cloudflare/types/zones/origin_error_page_pass_thru_param.py create mode 100644 src/cloudflare/types/zones/polish_param.py create mode 100644 src/cloudflare/types/zones/response_buffering_param.py create mode 100644 src/cloudflare/types/zones/rocket_loader_param.py create mode 100644 src/cloudflare/types/zones/security_level_param.py create mode 100644 src/cloudflare/types/zones/server_side_excludes_param.py create mode 100644 src/cloudflare/types/zones/sort_query_string_for_cache_param.py create mode 100644 src/cloudflare/types/zones/ssl_param.py create mode 100644 src/cloudflare/types/zones/true_client_ip_header_param.py create mode 100644 src/cloudflare/types/zones/waf_param.py create mode 100644 tests/api_resources/firewall/test_lockdowns.py create mode 100644 tests/api_resources/firewall/test_rules.py create mode 100644 tests/api_resources/firewall/test_ua_rules.py create mode 100644 tests/api_resources/firewall/waf/test_overrides.py create mode 100644 tests/api_resources/firewall/waf/test_packages.py delete mode 100644 tests/api_resources/pagerules/__init__.py delete mode 100644 tests/api_resources/pagerules/test_settings.py create mode 100644 tests/api_resources/test_filters.py create mode 100644 tests/api_resources/test_rate_limits.py diff --git a/.stats.yml b/.stats.yml index 96071d514cc..2e5ede7171d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 1408 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-9482a52799bf82c48325ec6462f86b2c70ade8214816411c9b104620ac94f73e.yml +configured_endpoints: 1448 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-46a81b24a8d697e3c5a31b8d3d7342a90e5af1e669ff4e463a6809cf6cb03771.yml diff --git a/api.md b/api.md index 44c5e2d0fdc..692bfb6d3d5 100644 --- a/api.md +++ b/api.md @@ -1476,9 +1476,24 @@ Methods: Types: ```python -from cloudflare.types.filters import FirewallFilter +from cloudflare.types.filters import ( + FirewallFilter, + FilterCreateResponse, + FilterBulkDeleteResponse, + FilterBulkUpdateResponse, +) ``` +Methods: + +- client.filters.create(\*, zone_id, \*\*params) -> Optional +- client.filters.update(filter_id, \*, zone_id, \*\*params) -> FirewallFilter +- client.filters.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[FirewallFilter] +- client.filters.delete(filter_id, \*, zone_id) -> FirewallFilter +- client.filters.bulk_delete(\*, zone_id) -> Optional +- client.filters.bulk_update(\*, zone_id) -> Optional +- client.filters.get(filter_id, \*, zone_id) -> FirewallFilter + # Firewall ## Lockdowns @@ -1492,17 +1507,47 @@ from cloudflare.types.firewall import ( LockdownCIDRConfiguration, LockdownIPConfiguration, LockdownURL, + LockdownDeleteResponse, ) ``` +Methods: + +- client.firewall.lockdowns.create(\*, zone_id, \*\*params) -> Lockdown +- client.firewall.lockdowns.update(lock_downs_id, \*, zone_id, \*\*params) -> Lockdown +- client.firewall.lockdowns.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[Lockdown] +- client.firewall.lockdowns.delete(lock_downs_id, \*, zone_id) -> Optional +- client.firewall.lockdowns.get(lock_downs_id, \*, zone_id) -> Lockdown + ## Rules Types: ```python -from cloudflare.types.firewall import FirewallRule, Product, DeletedFilter +from cloudflare.types.firewall import ( + FirewallRule, + Product, + DeletedFilter, + RuleCreateResponse, + RuleBulkDeleteResponse, + RuleBulkEditResponse, + RuleBulkUpdateResponse, + RuleEditResponse, +) ``` +Methods: + +- client.firewall.rules.create(\*, zone_id, \*\*params) -> Optional +- client.firewall.rules.update(rule_id, \*, zone_id, \*\*params) -> FirewallRule +- client.firewall.rules.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[FirewallRule] +- client.firewall.rules.delete(rule_id, \*, zone_id) -> FirewallRule +- client.firewall.rules.bulk_delete(\*, zone_id) -> Optional +- client.firewall.rules.bulk_edit(\*, zone_id, \*\*params) -> Optional +- client.firewall.rules.bulk_update(\*, zone_id, \*\*params) -> Optional +- client.firewall.rules.edit(rule_id, \*, zone_id) -> Optional +- client.firewall.rules.get(rule_id, \*, zone_id, \*\*params) -> FirewallRule + ## AccessRules Types: @@ -1516,13 +1561,41 @@ from cloudflare.types.firewall import ( IPV6Configuration, AccessRuleCreateResponse, AccessRuleListResponse, + AccessRuleDeleteResponse, + AccessRuleEditResponse, + AccessRuleGetResponse, ) ``` Methods: - client.firewall.access_rules.create(\*, account_id, zone_id, \*\*params) -> AccessRuleCreateResponse -- client.firewall.access_rules.list(\*, account_id, zone_id, \*\*params) -> SyncV4PagePaginationArray[object] +- client.firewall.access_rules.list(\*, account_id, zone_id, \*\*params) -> SyncV4PagePaginationArray[AccessRuleListResponse] +- client.firewall.access_rules.delete(rule_id, \*, account_id, zone_id) -> Optional +- client.firewall.access_rules.edit(rule_id, \*, account_id, zone_id, \*\*params) -> AccessRuleEditResponse +- client.firewall.access_rules.get(rule_id, \*, account_id, zone_id) -> AccessRuleGetResponse + +## UARules + +Types: + +```python +from cloudflare.types.firewall import ( + UARuleCreateResponse, + UARuleUpdateResponse, + UARuleListResponse, + UARuleDeleteResponse, + UARuleGetResponse, +) +``` + +Methods: + +- client.firewall.ua_rules.create(\*, zone_id, \*\*params) -> UARuleCreateResponse +- client.firewall.ua_rules.update(ua_rule_id, \*, zone_id, \*\*params) -> UARuleUpdateResponse +- client.firewall.ua_rules.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[UARuleListResponse] +- client.firewall.ua_rules.delete(ua_rule_id, \*, zone_id) -> UARuleDeleteResponse +- client.firewall.ua_rules.get(ua_rule_id, \*, zone_id) -> UARuleGetResponse ## WAF @@ -1531,11 +1604,36 @@ Methods: Types: ```python -from cloudflare.types.firewall.waf import Override, OverrideURL, RewriteAction, WAFRule +from cloudflare.types.firewall.waf import ( + Override, + OverrideURL, + RewriteAction, + WAFRule, + OverrideDeleteResponse, +) ``` +Methods: + +- client.firewall.waf.overrides.create(\*, zone_id, \*\*params) -> Override +- client.firewall.waf.overrides.update(overrides_id, \*, zone_id, \*\*params) -> Override +- client.firewall.waf.overrides.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[Override] +- client.firewall.waf.overrides.delete(overrides_id, \*, zone_id) -> Optional +- client.firewall.waf.overrides.get(overrides_id, \*, zone_id) -> Override + ### Packages +Types: + +```python +from cloudflare.types.firewall.waf import PackageListResponse, PackageGetResponse +``` + +Methods: + +- client.firewall.waf.packages.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[object] +- client.firewall.waf.packages.get(package_id, \*, zone_id) -> PackageGetResponse + #### Groups Types: @@ -1856,32 +1954,28 @@ from cloudflare.types.pagerules import ( Methods: -- client.pagerules.create(\*, zone_id, \*\*params) -> Optional -- client.pagerules.update(pagerule_id, \*, zone_id, \*\*params) -> Optional -- client.pagerules.list(\*, zone_id, \*\*params) -> Optional -- client.pagerules.delete(pagerule_id, \*, zone_id) -> Optional -- client.pagerules.edit(pagerule_id, \*, zone_id, \*\*params) -> Optional -- client.pagerules.get(pagerule_id, \*, zone_id) -> Optional +- client.pagerules.create(\*, zone_id, \*\*params) -> Optional +- client.pagerules.update(pagerule_id, \*, zone_id, \*\*params) -> Optional +- client.pagerules.list(\*, zone_id, \*\*params) -> Optional +- client.pagerules.delete(pagerule_id, \*, zone_id) -> Optional +- client.pagerules.edit(pagerule_id, \*, zone_id, \*\*params) -> Optional +- client.pagerules.get(pagerule_id, \*, zone_id) -> Optional -## Settings +# RateLimits Types: ```python -from cloudflare.types.pagerules import SettingListResponse +from cloudflare.types.rate_limits import Action, Methods, RateLimit, RateLimitDeleteResponse ``` Methods: -- client.pagerules.settings.list(\*, zone_id) -> Optional - -# RateLimits - -Types: - -```python -from cloudflare.types.rate_limits import Action, Methods, RateLimit -``` +- client.rate_limits.create(\*, zone_id, \*\*params) -> RateLimit +- client.rate_limits.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[RateLimit] +- client.rate_limits.delete(rate_limit_id, \*, zone_id) -> RateLimitDeleteResponse +- client.rate_limits.edit(rate_limit_id, \*, zone_id, \*\*params) -> RateLimit +- client.rate_limits.get(rate_limit_id, \*, zone_id) -> RateLimit # SecondaryDNS diff --git a/src/cloudflare/_client.py b/src/cloudflare/_client.py index f81d0484d8f..41ff9ac25d2 100644 --- a/src/cloudflare/_client.py +++ b/src/cloudflare/_client.py @@ -62,6 +62,7 @@ queues, stream, billing, + filters, logpush, storage, workers, @@ -87,6 +88,7 @@ diagnostics, memberships, page_shield, + rate_limits, url_scanner, healthchecks, security_txt, @@ -327,6 +329,12 @@ def email_routing(self) -> email_routing.EmailRoutingResource: return EmailRoutingResource(self) + @cached_property + def filters(self) -> filters.FiltersResource: + from .resources.filters import FiltersResource + + return FiltersResource(self) + @cached_property def firewall(self) -> firewall.FirewallResource: from .resources.firewall import FirewallResource @@ -369,6 +377,12 @@ def pagerules(self) -> pagerules.PagerulesResource: return PagerulesResource(self) + @cached_property + def rate_limits(self) -> rate_limits.RateLimitsResource: + from .resources.rate_limits import RateLimitsResource + + return RateLimitsResource(self) + @cached_property def secondary_dns(self) -> secondary_dns.SecondaryDNSResource: from .resources.secondary_dns import SecondaryDNSResource @@ -1086,6 +1100,12 @@ def email_routing(self) -> email_routing.AsyncEmailRoutingResource: return AsyncEmailRoutingResource(self) + @cached_property + def filters(self) -> filters.AsyncFiltersResource: + from .resources.filters import AsyncFiltersResource + + return AsyncFiltersResource(self) + @cached_property def firewall(self) -> firewall.AsyncFirewallResource: from .resources.firewall import AsyncFirewallResource @@ -1128,6 +1148,12 @@ def pagerules(self) -> pagerules.AsyncPagerulesResource: return AsyncPagerulesResource(self) + @cached_property + def rate_limits(self) -> rate_limits.AsyncRateLimitsResource: + from .resources.rate_limits import AsyncRateLimitsResource + + return AsyncRateLimitsResource(self) + @cached_property def secondary_dns(self) -> secondary_dns.AsyncSecondaryDNSResource: from .resources.secondary_dns import AsyncSecondaryDNSResource @@ -1778,6 +1804,12 @@ def email_routing(self) -> email_routing.EmailRoutingResourceWithRawResponse: return EmailRoutingResourceWithRawResponse(self._client.email_routing) + @cached_property + def filters(self) -> filters.FiltersResourceWithRawResponse: + from .resources.filters import FiltersResourceWithRawResponse + + return FiltersResourceWithRawResponse(self._client.filters) + @cached_property def firewall(self) -> firewall.FirewallResourceWithRawResponse: from .resources.firewall import FirewallResourceWithRawResponse @@ -1820,6 +1852,12 @@ def pagerules(self) -> pagerules.PagerulesResourceWithRawResponse: return PagerulesResourceWithRawResponse(self._client.pagerules) + @cached_property + def rate_limits(self) -> rate_limits.RateLimitsResourceWithRawResponse: + from .resources.rate_limits import RateLimitsResourceWithRawResponse + + return RateLimitsResourceWithRawResponse(self._client.rate_limits) + @cached_property def secondary_dns(self) -> secondary_dns.SecondaryDNSResourceWithRawResponse: from .resources.secondary_dns import SecondaryDNSResourceWithRawResponse @@ -2291,6 +2329,12 @@ def email_routing(self) -> email_routing.AsyncEmailRoutingResourceWithRawRespons return AsyncEmailRoutingResourceWithRawResponse(self._client.email_routing) + @cached_property + def filters(self) -> filters.AsyncFiltersResourceWithRawResponse: + from .resources.filters import AsyncFiltersResourceWithRawResponse + + return AsyncFiltersResourceWithRawResponse(self._client.filters) + @cached_property def firewall(self) -> firewall.AsyncFirewallResourceWithRawResponse: from .resources.firewall import AsyncFirewallResourceWithRawResponse @@ -2333,6 +2377,12 @@ def pagerules(self) -> pagerules.AsyncPagerulesResourceWithRawResponse: return AsyncPagerulesResourceWithRawResponse(self._client.pagerules) + @cached_property + def rate_limits(self) -> rate_limits.AsyncRateLimitsResourceWithRawResponse: + from .resources.rate_limits import AsyncRateLimitsResourceWithRawResponse + + return AsyncRateLimitsResourceWithRawResponse(self._client.rate_limits) + @cached_property def secondary_dns(self) -> secondary_dns.AsyncSecondaryDNSResourceWithRawResponse: from .resources.secondary_dns import AsyncSecondaryDNSResourceWithRawResponse @@ -2804,6 +2854,12 @@ def email_routing(self) -> email_routing.EmailRoutingResourceWithStreamingRespon return EmailRoutingResourceWithStreamingResponse(self._client.email_routing) + @cached_property + def filters(self) -> filters.FiltersResourceWithStreamingResponse: + from .resources.filters import FiltersResourceWithStreamingResponse + + return FiltersResourceWithStreamingResponse(self._client.filters) + @cached_property def firewall(self) -> firewall.FirewallResourceWithStreamingResponse: from .resources.firewall import FirewallResourceWithStreamingResponse @@ -2846,6 +2902,12 @@ def pagerules(self) -> pagerules.PagerulesResourceWithStreamingResponse: return PagerulesResourceWithStreamingResponse(self._client.pagerules) + @cached_property + def rate_limits(self) -> rate_limits.RateLimitsResourceWithStreamingResponse: + from .resources.rate_limits import RateLimitsResourceWithStreamingResponse + + return RateLimitsResourceWithStreamingResponse(self._client.rate_limits) + @cached_property def secondary_dns(self) -> secondary_dns.SecondaryDNSResourceWithStreamingResponse: from .resources.secondary_dns import SecondaryDNSResourceWithStreamingResponse @@ -3319,6 +3381,12 @@ def email_routing(self) -> email_routing.AsyncEmailRoutingResourceWithStreamingR return AsyncEmailRoutingResourceWithStreamingResponse(self._client.email_routing) + @cached_property + def filters(self) -> filters.AsyncFiltersResourceWithStreamingResponse: + from .resources.filters import AsyncFiltersResourceWithStreamingResponse + + return AsyncFiltersResourceWithStreamingResponse(self._client.filters) + @cached_property def firewall(self) -> firewall.AsyncFirewallResourceWithStreamingResponse: from .resources.firewall import AsyncFirewallResourceWithStreamingResponse @@ -3361,6 +3429,12 @@ def pagerules(self) -> pagerules.AsyncPagerulesResourceWithStreamingResponse: return AsyncPagerulesResourceWithStreamingResponse(self._client.pagerules) + @cached_property + def rate_limits(self) -> rate_limits.AsyncRateLimitsResourceWithStreamingResponse: + from .resources.rate_limits import AsyncRateLimitsResourceWithStreamingResponse + + return AsyncRateLimitsResourceWithStreamingResponse(self._client.rate_limits) + @cached_property def secondary_dns(self) -> secondary_dns.AsyncSecondaryDNSResourceWithStreamingResponse: from .resources.secondary_dns import AsyncSecondaryDNSResourceWithStreamingResponse diff --git a/src/cloudflare/resources/filters.py b/src/cloudflare/resources/filters.py new file mode 100644 index 00000000000..bda722a9a26 --- /dev/null +++ b/src/cloudflare/resources/filters.py @@ -0,0 +1,940 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import typing_extensions +from typing import Type, Optional, cast + +import httpx + +from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from .._utils import ( + maybe_transform, + async_maybe_transform, +) +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._wrappers import ResultWrapper +from ..pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from .._base_client import AsyncPaginator, make_request_options +from ..types.filters import filter_list_params, filter_create_params, filter_update_params +from ..types.filters.firewall_filter import FirewallFilter +from ..types.filters.filter_create_response import FilterCreateResponse +from ..types.filters.filter_bulk_delete_response import FilterBulkDeleteResponse +from ..types.filters.filter_bulk_update_response import FilterBulkUpdateResponse + +__all__ = ["FiltersResource", "AsyncFiltersResource"] + + +class FiltersResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> FiltersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return FiltersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> FiltersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return FiltersResourceWithStreamingResponse(self) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def create( + self, + *, + zone_id: str, + expression: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[FilterCreateResponse]: + """ + Creates one or more filters. + + Args: + zone_id: Identifier + + expression: The filter expression. For more information, refer to + [Expressions](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/). + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._post( + f"/zones/{zone_id}/filters", + body=maybe_transform({"expression": expression}, filter_create_params.FilterCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FilterCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FilterCreateResponse]], ResultWrapper[FilterCreateResponse]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def update( + self, + filter_id: str, + *, + zone_id: str, + body: object, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallFilter: + """ + Updates an existing filter. + + Args: + zone_id: Identifier + + filter_id: The unique identifier of the filter. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not filter_id: + raise ValueError(f"Expected a non-empty value for `filter_id` but received {filter_id!r}") + return self._put( + f"/zones/{zone_id}/filters/{filter_id}", + body=maybe_transform(body, filter_update_params.FilterUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallFilter]._unwrapper, + ), + cast_to=cast(Type[FirewallFilter], ResultWrapper[FirewallFilter]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def list( + self, + *, + zone_id: str, + id: str | NotGiven = NOT_GIVEN, + description: str | NotGiven = NOT_GIVEN, + expression: str | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + paused: bool | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + ref: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncV4PagePaginationArray[FirewallFilter]: + """Fetches filters in a zone. + + You can filter the results using several optional + parameters. + + Args: + zone_id: Identifier + + id: The unique identifier of the filter. + + description: A case-insensitive string to find in the description. + + expression: A case-insensitive string to find in the expression. + + page: Page number of paginated results. + + paused: When true, indicates that the filter is currently paused. + + per_page: Number of filters per page. + + ref: The filter ref (a short reference tag) to search for. Must be an exact match. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/filters", + page=SyncV4PagePaginationArray[FirewallFilter], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "id": id, + "description": description, + "expression": expression, + "page": page, + "paused": paused, + "per_page": per_page, + "ref": ref, + }, + filter_list_params.FilterListParams, + ), + ), + model=FirewallFilter, + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def delete( + self, + filter_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallFilter: + """ + Deletes an existing filter. + + Args: + zone_id: Identifier + + filter_id: The unique identifier of the filter. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not filter_id: + raise ValueError(f"Expected a non-empty value for `filter_id` but received {filter_id!r}") + return self._delete( + f"/zones/{zone_id}/filters/{filter_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallFilter]._unwrapper, + ), + cast_to=cast(Type[FirewallFilter], ResultWrapper[FirewallFilter]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def bulk_delete( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[FilterBulkDeleteResponse]: + """ + Deletes one or more existing filters. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._delete( + f"/zones/{zone_id}/filters", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FilterBulkDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FilterBulkDeleteResponse]], ResultWrapper[FilterBulkDeleteResponse]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def bulk_update( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[FilterBulkUpdateResponse]: + """ + Updates one or more existing filters. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._put( + f"/zones/{zone_id}/filters", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FilterBulkUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FilterBulkUpdateResponse]], ResultWrapper[FilterBulkUpdateResponse]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def get( + self, + filter_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallFilter: + """ + Fetches the details of a filter. + + Args: + zone_id: Identifier + + filter_id: The unique identifier of the filter. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not filter_id: + raise ValueError(f"Expected a non-empty value for `filter_id` but received {filter_id!r}") + return self._get( + f"/zones/{zone_id}/filters/{filter_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallFilter]._unwrapper, + ), + cast_to=cast(Type[FirewallFilter], ResultWrapper[FirewallFilter]), + ) + + +class AsyncFiltersResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncFiltersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncFiltersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncFiltersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncFiltersResourceWithStreamingResponse(self) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def create( + self, + *, + zone_id: str, + expression: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[FilterCreateResponse]: + """ + Creates one or more filters. + + Args: + zone_id: Identifier + + expression: The filter expression. For more information, refer to + [Expressions](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/). + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._post( + f"/zones/{zone_id}/filters", + body=await async_maybe_transform({"expression": expression}, filter_create_params.FilterCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FilterCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FilterCreateResponse]], ResultWrapper[FilterCreateResponse]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def update( + self, + filter_id: str, + *, + zone_id: str, + body: object, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallFilter: + """ + Updates an existing filter. + + Args: + zone_id: Identifier + + filter_id: The unique identifier of the filter. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not filter_id: + raise ValueError(f"Expected a non-empty value for `filter_id` but received {filter_id!r}") + return await self._put( + f"/zones/{zone_id}/filters/{filter_id}", + body=await async_maybe_transform(body, filter_update_params.FilterUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallFilter]._unwrapper, + ), + cast_to=cast(Type[FirewallFilter], ResultWrapper[FirewallFilter]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def list( + self, + *, + zone_id: str, + id: str | NotGiven = NOT_GIVEN, + description: str | NotGiven = NOT_GIVEN, + expression: str | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + paused: bool | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + ref: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[FirewallFilter, AsyncV4PagePaginationArray[FirewallFilter]]: + """Fetches filters in a zone. + + You can filter the results using several optional + parameters. + + Args: + zone_id: Identifier + + id: The unique identifier of the filter. + + description: A case-insensitive string to find in the description. + + expression: A case-insensitive string to find in the expression. + + page: Page number of paginated results. + + paused: When true, indicates that the filter is currently paused. + + per_page: Number of filters per page. + + ref: The filter ref (a short reference tag) to search for. Must be an exact match. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/filters", + page=AsyncV4PagePaginationArray[FirewallFilter], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "id": id, + "description": description, + "expression": expression, + "page": page, + "paused": paused, + "per_page": per_page, + "ref": ref, + }, + filter_list_params.FilterListParams, + ), + ), + model=FirewallFilter, + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def delete( + self, + filter_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallFilter: + """ + Deletes an existing filter. + + Args: + zone_id: Identifier + + filter_id: The unique identifier of the filter. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not filter_id: + raise ValueError(f"Expected a non-empty value for `filter_id` but received {filter_id!r}") + return await self._delete( + f"/zones/{zone_id}/filters/{filter_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallFilter]._unwrapper, + ), + cast_to=cast(Type[FirewallFilter], ResultWrapper[FirewallFilter]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def bulk_delete( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[FilterBulkDeleteResponse]: + """ + Deletes one or more existing filters. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._delete( + f"/zones/{zone_id}/filters", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FilterBulkDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FilterBulkDeleteResponse]], ResultWrapper[FilterBulkDeleteResponse]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def bulk_update( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[FilterBulkUpdateResponse]: + """ + Updates one or more existing filters. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._put( + f"/zones/{zone_id}/filters", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FilterBulkUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FilterBulkUpdateResponse]], ResultWrapper[FilterBulkUpdateResponse]), + ) + + @typing_extensions.deprecated( + "The Filters API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def get( + self, + filter_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallFilter: + """ + Fetches the details of a filter. + + Args: + zone_id: Identifier + + filter_id: The unique identifier of the filter. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not filter_id: + raise ValueError(f"Expected a non-empty value for `filter_id` but received {filter_id!r}") + return await self._get( + f"/zones/{zone_id}/filters/{filter_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallFilter]._unwrapper, + ), + cast_to=cast(Type[FirewallFilter], ResultWrapper[FirewallFilter]), + ) + + +class FiltersResourceWithRawResponse: + def __init__(self, filters: FiltersResource) -> None: + self._filters = filters + + self.create = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + filters.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + filters.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + filters.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + filters.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + filters.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + filters.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + filters.get # pyright: ignore[reportDeprecated], + ) + ) + + +class AsyncFiltersResourceWithRawResponse: + def __init__(self, filters: AsyncFiltersResource) -> None: + self._filters = filters + + self.create = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + filters.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + filters.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + filters.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + filters.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + filters.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + filters.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + filters.get # pyright: ignore[reportDeprecated], + ) + ) + + +class FiltersResourceWithStreamingResponse: + def __init__(self, filters: FiltersResource) -> None: + self._filters = filters + + self.create = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + filters.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + filters.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + filters.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + filters.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + filters.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + filters.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + filters.get # pyright: ignore[reportDeprecated], + ) + ) + + +class AsyncFiltersResourceWithStreamingResponse: + def __init__(self, filters: AsyncFiltersResource) -> None: + self._filters = filters + + self.create = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + filters.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + filters.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + filters.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + filters.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + filters.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + filters.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + filters.get # pyright: ignore[reportDeprecated], + ) + ) diff --git a/src/cloudflare/resources/firewall/__init__.py b/src/cloudflare/resources/firewall/__init__.py index 53adfca9ab6..cc405a6f65f 100644 --- a/src/cloudflare/resources/firewall/__init__.py +++ b/src/cloudflare/resources/firewall/__init__.py @@ -8,6 +8,14 @@ WAFResourceWithStreamingResponse, AsyncWAFResourceWithStreamingResponse, ) +from .rules import ( + RulesResource, + AsyncRulesResource, + RulesResourceWithRawResponse, + AsyncRulesResourceWithRawResponse, + RulesResourceWithStreamingResponse, + AsyncRulesResourceWithStreamingResponse, +) from .firewall import ( FirewallResource, AsyncFirewallResource, @@ -16,6 +24,22 @@ FirewallResourceWithStreamingResponse, AsyncFirewallResourceWithStreamingResponse, ) +from .ua_rules import ( + UARulesResource, + AsyncUARulesResource, + UARulesResourceWithRawResponse, + AsyncUARulesResourceWithRawResponse, + UARulesResourceWithStreamingResponse, + AsyncUARulesResourceWithStreamingResponse, +) +from .lockdowns import ( + LockdownsResource, + AsyncLockdownsResource, + LockdownsResourceWithRawResponse, + AsyncLockdownsResourceWithRawResponse, + LockdownsResourceWithStreamingResponse, + AsyncLockdownsResourceWithStreamingResponse, +) from .access_rules import ( AccessRulesResource, AsyncAccessRulesResource, @@ -26,12 +50,30 @@ ) __all__ = [ + "LockdownsResource", + "AsyncLockdownsResource", + "LockdownsResourceWithRawResponse", + "AsyncLockdownsResourceWithRawResponse", + "LockdownsResourceWithStreamingResponse", + "AsyncLockdownsResourceWithStreamingResponse", + "RulesResource", + "AsyncRulesResource", + "RulesResourceWithRawResponse", + "AsyncRulesResourceWithRawResponse", + "RulesResourceWithStreamingResponse", + "AsyncRulesResourceWithStreamingResponse", "AccessRulesResource", "AsyncAccessRulesResource", "AccessRulesResourceWithRawResponse", "AsyncAccessRulesResourceWithRawResponse", "AccessRulesResourceWithStreamingResponse", "AsyncAccessRulesResourceWithStreamingResponse", + "UARulesResource", + "AsyncUARulesResource", + "UARulesResourceWithRawResponse", + "AsyncUARulesResourceWithRawResponse", + "UARulesResourceWithStreamingResponse", + "AsyncUARulesResourceWithStreamingResponse", "WAFResource", "AsyncWAFResource", "WAFResourceWithRawResponse", diff --git a/src/cloudflare/resources/firewall/access_rules.py b/src/cloudflare/resources/firewall/access_rules.py index 0d12de27913..0cc4d0281e2 100644 --- a/src/cloudflare/resources/firewall/access_rules.py +++ b/src/cloudflare/resources/firewall/access_rules.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, cast +from typing import Type, Optional, cast from typing_extensions import Literal import httpx @@ -23,8 +23,12 @@ from ..._wrappers import ResultWrapper from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ..._base_client import AsyncPaginator, make_request_options -from ...types.firewall import access_rule_list_params, access_rule_create_params +from ...types.firewall import access_rule_edit_params, access_rule_list_params, access_rule_create_params +from ...types.firewall.access_rule_get_response import AccessRuleGetResponse +from ...types.firewall.access_rule_edit_response import AccessRuleEditResponse +from ...types.firewall.access_rule_list_response import AccessRuleListResponse from ...types.firewall.access_rule_create_response import AccessRuleCreateResponse +from ...types.firewall.access_rule_delete_response import AccessRuleDeleteResponse __all__ = ["AccessRulesResource", "AsyncAccessRulesResource"] @@ -103,29 +107,24 @@ def create( account_or_zone = "zones" account_or_zone_id = zone_id - return cast( - AccessRuleCreateResponse, - self._post( - f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules", - body=maybe_transform( - { - "configuration": configuration, - "mode": mode, - "notes": notes, - }, - access_rule_create_params.AccessRuleCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AccessRuleCreateResponse]._unwrapper, - ), - cast_to=cast( - Any, ResultWrapper[AccessRuleCreateResponse] - ), # Union types cannot be passed in as arguments in the type system + return self._post( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules", + body=maybe_transform( + { + "configuration": configuration, + "mode": mode, + "notes": notes, + }, + access_rule_create_params.AccessRuleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[AccessRuleCreateResponse]._unwrapper, ), + cast_to=cast(Type[AccessRuleCreateResponse], ResultWrapper[AccessRuleCreateResponse]), ) def list( @@ -147,7 +146,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> SyncV4PagePaginationArray[object]: + ) -> SyncV4PagePaginationArray[AccessRuleListResponse]: """Fetches IP Access rules of an account or zone. These rules apply to all the @@ -198,7 +197,7 @@ def list( account_or_zone_id = zone_id return self._get_api_list( f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules", - page=SyncV4PagePaginationArray[object], + page=SyncV4PagePaginationArray[AccessRuleListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -218,7 +217,199 @@ def list( access_rule_list_params.AccessRuleListParams, ), ), - model=object, + model=AccessRuleListResponse, + ) + + def delete( + self, + rule_id: str, + *, + account_id: str | NotGiven = NOT_GIVEN, + zone_id: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[AccessRuleDeleteResponse]: + """ + Deletes an existing IP Access rule defined. + + Note: This operation will affect all zones in the account or zone. + + Args: + rule_id: Unique identifier for a rule + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + if account_id and zone_id: + raise ValueError("You cannot provide both account_id and zone_id") + + if account_id: + account_or_zone = "accounts" + account_or_zone_id = account_id + else: + if not zone_id: + raise ValueError("You must provide either account_id or zone_id") + + account_or_zone = "zones" + account_or_zone_id = zone_id + return self._delete( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[AccessRuleDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[AccessRuleDeleteResponse]], ResultWrapper[AccessRuleDeleteResponse]), + ) + + def edit( + self, + rule_id: str, + *, + configuration: access_rule_edit_params.Configuration, + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"], + account_id: str | NotGiven = NOT_GIVEN, + zone_id: str | NotGiven = NOT_GIVEN, + notes: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AccessRuleEditResponse: + """ + Updates an IP Access rule defined. + + Note: This operation will affect all zones in the account or zone. + + Args: + rule_id: Unique identifier for a rule + + configuration: The rule configuration. + + mode: The action to apply to a matched request. + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + notes: An informative summary of the rule, typically used as a reminder or explanation. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + if account_id and zone_id: + raise ValueError("You cannot provide both account_id and zone_id") + + if account_id: + account_or_zone = "accounts" + account_or_zone_id = account_id + else: + if not zone_id: + raise ValueError("You must provide either account_id or zone_id") + + account_or_zone = "zones" + account_or_zone_id = zone_id + return self._patch( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules/{rule_id}", + body=maybe_transform( + { + "configuration": configuration, + "mode": mode, + "notes": notes, + }, + access_rule_edit_params.AccessRuleEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[AccessRuleEditResponse]._unwrapper, + ), + cast_to=cast(Type[AccessRuleEditResponse], ResultWrapper[AccessRuleEditResponse]), + ) + + def get( + self, + rule_id: str, + *, + account_id: str | NotGiven = NOT_GIVEN, + zone_id: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AccessRuleGetResponse: + """ + Fetches the details of an IP Access rule defined. + + Args: + rule_id: Unique identifier for a rule + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + if account_id and zone_id: + raise ValueError("You cannot provide both account_id and zone_id") + + if account_id: + account_or_zone = "accounts" + account_or_zone_id = account_id + else: + if not zone_id: + raise ValueError("You must provide either account_id or zone_id") + + account_or_zone = "zones" + account_or_zone_id = zone_id + return self._get( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[AccessRuleGetResponse]._unwrapper, + ), + cast_to=cast(Type[AccessRuleGetResponse], ResultWrapper[AccessRuleGetResponse]), ) @@ -296,29 +487,24 @@ async def create( account_or_zone = "zones" account_or_zone_id = zone_id - return cast( - AccessRuleCreateResponse, - await self._post( - f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules", - body=await async_maybe_transform( - { - "configuration": configuration, - "mode": mode, - "notes": notes, - }, - access_rule_create_params.AccessRuleCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AccessRuleCreateResponse]._unwrapper, - ), - cast_to=cast( - Any, ResultWrapper[AccessRuleCreateResponse] - ), # Union types cannot be passed in as arguments in the type system + return await self._post( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules", + body=await async_maybe_transform( + { + "configuration": configuration, + "mode": mode, + "notes": notes, + }, + access_rule_create_params.AccessRuleCreateParams, ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[AccessRuleCreateResponse]._unwrapper, + ), + cast_to=cast(Type[AccessRuleCreateResponse], ResultWrapper[AccessRuleCreateResponse]), ) def list( @@ -340,7 +526,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[object, AsyncV4PagePaginationArray[object]]: + ) -> AsyncPaginator[AccessRuleListResponse, AsyncV4PagePaginationArray[AccessRuleListResponse]]: """Fetches IP Access rules of an account or zone. These rules apply to all the @@ -391,7 +577,7 @@ def list( account_or_zone_id = zone_id return self._get_api_list( f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules", - page=AsyncV4PagePaginationArray[object], + page=AsyncV4PagePaginationArray[AccessRuleListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -411,7 +597,199 @@ def list( access_rule_list_params.AccessRuleListParams, ), ), - model=object, + model=AccessRuleListResponse, + ) + + async def delete( + self, + rule_id: str, + *, + account_id: str | NotGiven = NOT_GIVEN, + zone_id: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[AccessRuleDeleteResponse]: + """ + Deletes an existing IP Access rule defined. + + Note: This operation will affect all zones in the account or zone. + + Args: + rule_id: Unique identifier for a rule + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + if account_id and zone_id: + raise ValueError("You cannot provide both account_id and zone_id") + + if account_id: + account_or_zone = "accounts" + account_or_zone_id = account_id + else: + if not zone_id: + raise ValueError("You must provide either account_id or zone_id") + + account_or_zone = "zones" + account_or_zone_id = zone_id + return await self._delete( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[AccessRuleDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[AccessRuleDeleteResponse]], ResultWrapper[AccessRuleDeleteResponse]), + ) + + async def edit( + self, + rule_id: str, + *, + configuration: access_rule_edit_params.Configuration, + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"], + account_id: str | NotGiven = NOT_GIVEN, + zone_id: str | NotGiven = NOT_GIVEN, + notes: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AccessRuleEditResponse: + """ + Updates an IP Access rule defined. + + Note: This operation will affect all zones in the account or zone. + + Args: + rule_id: Unique identifier for a rule + + configuration: The rule configuration. + + mode: The action to apply to a matched request. + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + notes: An informative summary of the rule, typically used as a reminder or explanation. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + if account_id and zone_id: + raise ValueError("You cannot provide both account_id and zone_id") + + if account_id: + account_or_zone = "accounts" + account_or_zone_id = account_id + else: + if not zone_id: + raise ValueError("You must provide either account_id or zone_id") + + account_or_zone = "zones" + account_or_zone_id = zone_id + return await self._patch( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules/{rule_id}", + body=await async_maybe_transform( + { + "configuration": configuration, + "mode": mode, + "notes": notes, + }, + access_rule_edit_params.AccessRuleEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[AccessRuleEditResponse]._unwrapper, + ), + cast_to=cast(Type[AccessRuleEditResponse], ResultWrapper[AccessRuleEditResponse]), + ) + + async def get( + self, + rule_id: str, + *, + account_id: str | NotGiven = NOT_GIVEN, + zone_id: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AccessRuleGetResponse: + """ + Fetches the details of an IP Access rule defined. + + Args: + rule_id: Unique identifier for a rule + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + if account_id and zone_id: + raise ValueError("You cannot provide both account_id and zone_id") + + if account_id: + account_or_zone = "accounts" + account_or_zone_id = account_id + else: + if not zone_id: + raise ValueError("You must provide either account_id or zone_id") + + account_or_zone = "zones" + account_or_zone_id = zone_id + return await self._get( + f"/{account_or_zone}/{account_or_zone_id}/firewall/access_rules/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[AccessRuleGetResponse]._unwrapper, + ), + cast_to=cast(Type[AccessRuleGetResponse], ResultWrapper[AccessRuleGetResponse]), ) @@ -425,6 +803,15 @@ def __init__(self, access_rules: AccessRulesResource) -> None: self.list = to_raw_response_wrapper( access_rules.list, ) + self.delete = to_raw_response_wrapper( + access_rules.delete, + ) + self.edit = to_raw_response_wrapper( + access_rules.edit, + ) + self.get = to_raw_response_wrapper( + access_rules.get, + ) class AsyncAccessRulesResourceWithRawResponse: @@ -437,6 +824,15 @@ def __init__(self, access_rules: AsyncAccessRulesResource) -> None: self.list = async_to_raw_response_wrapper( access_rules.list, ) + self.delete = async_to_raw_response_wrapper( + access_rules.delete, + ) + self.edit = async_to_raw_response_wrapper( + access_rules.edit, + ) + self.get = async_to_raw_response_wrapper( + access_rules.get, + ) class AccessRulesResourceWithStreamingResponse: @@ -449,6 +845,15 @@ def __init__(self, access_rules: AccessRulesResource) -> None: self.list = to_streamed_response_wrapper( access_rules.list, ) + self.delete = to_streamed_response_wrapper( + access_rules.delete, + ) + self.edit = to_streamed_response_wrapper( + access_rules.edit, + ) + self.get = to_streamed_response_wrapper( + access_rules.get, + ) class AsyncAccessRulesResourceWithStreamingResponse: @@ -461,3 +866,12 @@ def __init__(self, access_rules: AsyncAccessRulesResource) -> None: self.list = async_to_streamed_response_wrapper( access_rules.list, ) + self.delete = async_to_streamed_response_wrapper( + access_rules.delete, + ) + self.edit = async_to_streamed_response_wrapper( + access_rules.edit, + ) + self.get = async_to_streamed_response_wrapper( + access_rules.get, + ) diff --git a/src/cloudflare/resources/firewall/firewall.py b/src/cloudflare/resources/firewall/firewall.py index 6cfa5c1d6da..e5ff2fe9261 100644 --- a/src/cloudflare/resources/firewall/firewall.py +++ b/src/cloudflare/resources/firewall/firewall.py @@ -10,8 +10,32 @@ WAFResourceWithStreamingResponse, AsyncWAFResourceWithStreamingResponse, ) +from .rules import ( + RulesResource, + AsyncRulesResource, + RulesResourceWithRawResponse, + AsyncRulesResourceWithRawResponse, + RulesResourceWithStreamingResponse, + AsyncRulesResourceWithStreamingResponse, +) from .waf.waf import WAFResource, AsyncWAFResource +from .ua_rules import ( + UARulesResource, + AsyncUARulesResource, + UARulesResourceWithRawResponse, + AsyncUARulesResourceWithRawResponse, + UARulesResourceWithStreamingResponse, + AsyncUARulesResourceWithStreamingResponse, +) from ..._compat import cached_property +from .lockdowns import ( + LockdownsResource, + AsyncLockdownsResource, + LockdownsResourceWithRawResponse, + AsyncLockdownsResourceWithRawResponse, + LockdownsResourceWithStreamingResponse, + AsyncLockdownsResourceWithStreamingResponse, +) from ..._resource import SyncAPIResource, AsyncAPIResource from .access_rules import ( AccessRulesResource, @@ -26,10 +50,22 @@ class FirewallResource(SyncAPIResource): + @cached_property + def lockdowns(self) -> LockdownsResource: + return LockdownsResource(self._client) + + @cached_property + def rules(self) -> RulesResource: + return RulesResource(self._client) + @cached_property def access_rules(self) -> AccessRulesResource: return AccessRulesResource(self._client) + @cached_property + def ua_rules(self) -> UARulesResource: + return UARulesResource(self._client) + @cached_property def waf(self) -> WAFResource: return WAFResource(self._client) @@ -55,10 +91,22 @@ def with_streaming_response(self) -> FirewallResourceWithStreamingResponse: class AsyncFirewallResource(AsyncAPIResource): + @cached_property + def lockdowns(self) -> AsyncLockdownsResource: + return AsyncLockdownsResource(self._client) + + @cached_property + def rules(self) -> AsyncRulesResource: + return AsyncRulesResource(self._client) + @cached_property def access_rules(self) -> AsyncAccessRulesResource: return AsyncAccessRulesResource(self._client) + @cached_property + def ua_rules(self) -> AsyncUARulesResource: + return AsyncUARulesResource(self._client) + @cached_property def waf(self) -> AsyncWAFResource: return AsyncWAFResource(self._client) @@ -87,10 +135,22 @@ class FirewallResourceWithRawResponse: def __init__(self, firewall: FirewallResource) -> None: self._firewall = firewall + @cached_property + def lockdowns(self) -> LockdownsResourceWithRawResponse: + return LockdownsResourceWithRawResponse(self._firewall.lockdowns) + + @cached_property + def rules(self) -> RulesResourceWithRawResponse: + return RulesResourceWithRawResponse(self._firewall.rules) + @cached_property def access_rules(self) -> AccessRulesResourceWithRawResponse: return AccessRulesResourceWithRawResponse(self._firewall.access_rules) + @cached_property + def ua_rules(self) -> UARulesResourceWithRawResponse: + return UARulesResourceWithRawResponse(self._firewall.ua_rules) + @cached_property def waf(self) -> WAFResourceWithRawResponse: return WAFResourceWithRawResponse(self._firewall.waf) @@ -100,10 +160,22 @@ class AsyncFirewallResourceWithRawResponse: def __init__(self, firewall: AsyncFirewallResource) -> None: self._firewall = firewall + @cached_property + def lockdowns(self) -> AsyncLockdownsResourceWithRawResponse: + return AsyncLockdownsResourceWithRawResponse(self._firewall.lockdowns) + + @cached_property + def rules(self) -> AsyncRulesResourceWithRawResponse: + return AsyncRulesResourceWithRawResponse(self._firewall.rules) + @cached_property def access_rules(self) -> AsyncAccessRulesResourceWithRawResponse: return AsyncAccessRulesResourceWithRawResponse(self._firewall.access_rules) + @cached_property + def ua_rules(self) -> AsyncUARulesResourceWithRawResponse: + return AsyncUARulesResourceWithRawResponse(self._firewall.ua_rules) + @cached_property def waf(self) -> AsyncWAFResourceWithRawResponse: return AsyncWAFResourceWithRawResponse(self._firewall.waf) @@ -113,10 +185,22 @@ class FirewallResourceWithStreamingResponse: def __init__(self, firewall: FirewallResource) -> None: self._firewall = firewall + @cached_property + def lockdowns(self) -> LockdownsResourceWithStreamingResponse: + return LockdownsResourceWithStreamingResponse(self._firewall.lockdowns) + + @cached_property + def rules(self) -> RulesResourceWithStreamingResponse: + return RulesResourceWithStreamingResponse(self._firewall.rules) + @cached_property def access_rules(self) -> AccessRulesResourceWithStreamingResponse: return AccessRulesResourceWithStreamingResponse(self._firewall.access_rules) + @cached_property + def ua_rules(self) -> UARulesResourceWithStreamingResponse: + return UARulesResourceWithStreamingResponse(self._firewall.ua_rules) + @cached_property def waf(self) -> WAFResourceWithStreamingResponse: return WAFResourceWithStreamingResponse(self._firewall.waf) @@ -126,10 +210,22 @@ class AsyncFirewallResourceWithStreamingResponse: def __init__(self, firewall: AsyncFirewallResource) -> None: self._firewall = firewall + @cached_property + def lockdowns(self) -> AsyncLockdownsResourceWithStreamingResponse: + return AsyncLockdownsResourceWithStreamingResponse(self._firewall.lockdowns) + + @cached_property + def rules(self) -> AsyncRulesResourceWithStreamingResponse: + return AsyncRulesResourceWithStreamingResponse(self._firewall.rules) + @cached_property def access_rules(self) -> AsyncAccessRulesResourceWithStreamingResponse: return AsyncAccessRulesResourceWithStreamingResponse(self._firewall.access_rules) + @cached_property + def ua_rules(self) -> AsyncUARulesResourceWithStreamingResponse: + return AsyncUARulesResourceWithStreamingResponse(self._firewall.ua_rules) + @cached_property def waf(self) -> AsyncWAFResourceWithStreamingResponse: return AsyncWAFResourceWithStreamingResponse(self._firewall.waf) diff --git a/src/cloudflare/resources/firewall/lockdowns.py b/src/cloudflare/resources/firewall/lockdowns.py new file mode 100644 index 00000000000..94dd5f36c30 --- /dev/null +++ b/src/cloudflare/resources/firewall/lockdowns.py @@ -0,0 +1,754 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Type, Union, Optional, cast +from datetime import datetime + +import httpx + +from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ..._utils import ( + maybe_transform, + async_maybe_transform, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._wrappers import ResultWrapper +from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ..._base_client import AsyncPaginator, make_request_options +from ...types.firewall import lockdown_list_params, lockdown_create_params, lockdown_update_params +from ...types.firewall.lockdown import Lockdown +from ...types.firewall.waf.override_url import OverrideURL +from ...types.firewall.configuration_param import ConfigurationParam +from ...types.firewall.lockdown_delete_response import LockdownDeleteResponse + +__all__ = ["LockdownsResource", "AsyncLockdownsResource"] + + +class LockdownsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> LockdownsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return LockdownsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> LockdownsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return LockdownsResourceWithStreamingResponse(self) + + def create( + self, + *, + zone_id: str, + configurations: ConfigurationParam, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Lockdown: + """ + Creates a new Zone Lockdown rule. + + Args: + zone_id: Identifier + + configurations: A list of IP addresses or CIDR ranges that will be allowed to access the URLs + specified in the Zone Lockdown rule. You can include any number of `ip` or + `ip_range` configurations. + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._post( + f"/zones/{zone_id}/firewall/lockdowns", + body=maybe_transform( + { + "configurations": configurations, + "urls": urls, + }, + lockdown_create_params.LockdownCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Lockdown]._unwrapper, + ), + cast_to=cast(Type[Lockdown], ResultWrapper[Lockdown]), + ) + + def update( + self, + lock_downs_id: str, + *, + zone_id: str, + configurations: ConfigurationParam, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Lockdown: + """ + Updates an existing Zone Lockdown rule. + + Args: + zone_id: Identifier + + lock_downs_id: The unique identifier of the Zone Lockdown rule. + + configurations: A list of IP addresses or CIDR ranges that will be allowed to access the URLs + specified in the Zone Lockdown rule. You can include any number of `ip` or + `ip_range` configurations. + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not lock_downs_id: + raise ValueError(f"Expected a non-empty value for `lock_downs_id` but received {lock_downs_id!r}") + return self._put( + f"/zones/{zone_id}/firewall/lockdowns/{lock_downs_id}", + body=maybe_transform( + { + "configurations": configurations, + "urls": urls, + }, + lockdown_update_params.LockdownUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Lockdown]._unwrapper, + ), + cast_to=cast(Type[Lockdown], ResultWrapper[Lockdown]), + ) + + def list( + self, + *, + zone_id: str, + created_on: Union[str, datetime] | NotGiven = NOT_GIVEN, + description: str | NotGiven = NOT_GIVEN, + description_search: str | NotGiven = NOT_GIVEN, + ip: str | NotGiven = NOT_GIVEN, + ip_range_search: str | NotGiven = NOT_GIVEN, + ip_search: str | NotGiven = NOT_GIVEN, + modified_on: Union[str, datetime] | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + priority: float | NotGiven = NOT_GIVEN, + uri_search: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncV4PagePaginationArray[Lockdown]: + """Fetches Zone Lockdown rules. + + You can filter the results using several optional + parameters. + + Args: + zone_id: Identifier + + created_on: The timestamp of when the rule was created. + + description: A string to search for in the description of existing rules. + + description_search: A string to search for in the description of existing rules. + + ip: A single IP address to search for in existing rules. + + ip_range_search: A single IP address range to search for in existing rules. + + ip_search: A single IP address to search for in existing rules. + + modified_on: The timestamp of when the rule was last modified. + + page: Page number of paginated results. + + per_page: The maximum number of results per page. You can only set the value to `1` or to + a multiple of 5 such as `5`, `10`, `15`, or `20`. + + priority: The priority of the rule to control the processing order. A lower number + indicates higher priority. If not provided, any rules with a configured priority + will be processed before rules without a priority. + + uri_search: A single URI to search for in the list of URLs of existing rules. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/lockdowns", + page=SyncV4PagePaginationArray[Lockdown], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "created_on": created_on, + "description": description, + "description_search": description_search, + "ip": ip, + "ip_range_search": ip_range_search, + "ip_search": ip_search, + "modified_on": modified_on, + "page": page, + "per_page": per_page, + "priority": priority, + "uri_search": uri_search, + }, + lockdown_list_params.LockdownListParams, + ), + ), + model=Lockdown, + ) + + def delete( + self, + lock_downs_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[LockdownDeleteResponse]: + """ + Deletes an existing Zone Lockdown rule. + + Args: + zone_id: Identifier + + lock_downs_id: The unique identifier of the Zone Lockdown rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not lock_downs_id: + raise ValueError(f"Expected a non-empty value for `lock_downs_id` but received {lock_downs_id!r}") + return self._delete( + f"/zones/{zone_id}/firewall/lockdowns/{lock_downs_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[LockdownDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[LockdownDeleteResponse]], ResultWrapper[LockdownDeleteResponse]), + ) + + def get( + self, + lock_downs_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Lockdown: + """ + Fetches the details of a Zone Lockdown rule. + + Args: + zone_id: Identifier + + lock_downs_id: The unique identifier of the Zone Lockdown rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not lock_downs_id: + raise ValueError(f"Expected a non-empty value for `lock_downs_id` but received {lock_downs_id!r}") + return self._get( + f"/zones/{zone_id}/firewall/lockdowns/{lock_downs_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Lockdown]._unwrapper, + ), + cast_to=cast(Type[Lockdown], ResultWrapper[Lockdown]), + ) + + +class AsyncLockdownsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncLockdownsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncLockdownsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncLockdownsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncLockdownsResourceWithStreamingResponse(self) + + async def create( + self, + *, + zone_id: str, + configurations: ConfigurationParam, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Lockdown: + """ + Creates a new Zone Lockdown rule. + + Args: + zone_id: Identifier + + configurations: A list of IP addresses or CIDR ranges that will be allowed to access the URLs + specified in the Zone Lockdown rule. You can include any number of `ip` or + `ip_range` configurations. + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._post( + f"/zones/{zone_id}/firewall/lockdowns", + body=await async_maybe_transform( + { + "configurations": configurations, + "urls": urls, + }, + lockdown_create_params.LockdownCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Lockdown]._unwrapper, + ), + cast_to=cast(Type[Lockdown], ResultWrapper[Lockdown]), + ) + + async def update( + self, + lock_downs_id: str, + *, + zone_id: str, + configurations: ConfigurationParam, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Lockdown: + """ + Updates an existing Zone Lockdown rule. + + Args: + zone_id: Identifier + + lock_downs_id: The unique identifier of the Zone Lockdown rule. + + configurations: A list of IP addresses or CIDR ranges that will be allowed to access the URLs + specified in the Zone Lockdown rule. You can include any number of `ip` or + `ip_range` configurations. + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not lock_downs_id: + raise ValueError(f"Expected a non-empty value for `lock_downs_id` but received {lock_downs_id!r}") + return await self._put( + f"/zones/{zone_id}/firewall/lockdowns/{lock_downs_id}", + body=await async_maybe_transform( + { + "configurations": configurations, + "urls": urls, + }, + lockdown_update_params.LockdownUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Lockdown]._unwrapper, + ), + cast_to=cast(Type[Lockdown], ResultWrapper[Lockdown]), + ) + + def list( + self, + *, + zone_id: str, + created_on: Union[str, datetime] | NotGiven = NOT_GIVEN, + description: str | NotGiven = NOT_GIVEN, + description_search: str | NotGiven = NOT_GIVEN, + ip: str | NotGiven = NOT_GIVEN, + ip_range_search: str | NotGiven = NOT_GIVEN, + ip_search: str | NotGiven = NOT_GIVEN, + modified_on: Union[str, datetime] | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + priority: float | NotGiven = NOT_GIVEN, + uri_search: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[Lockdown, AsyncV4PagePaginationArray[Lockdown]]: + """Fetches Zone Lockdown rules. + + You can filter the results using several optional + parameters. + + Args: + zone_id: Identifier + + created_on: The timestamp of when the rule was created. + + description: A string to search for in the description of existing rules. + + description_search: A string to search for in the description of existing rules. + + ip: A single IP address to search for in existing rules. + + ip_range_search: A single IP address range to search for in existing rules. + + ip_search: A single IP address to search for in existing rules. + + modified_on: The timestamp of when the rule was last modified. + + page: Page number of paginated results. + + per_page: The maximum number of results per page. You can only set the value to `1` or to + a multiple of 5 such as `5`, `10`, `15`, or `20`. + + priority: The priority of the rule to control the processing order. A lower number + indicates higher priority. If not provided, any rules with a configured priority + will be processed before rules without a priority. + + uri_search: A single URI to search for in the list of URLs of existing rules. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/lockdowns", + page=AsyncV4PagePaginationArray[Lockdown], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "created_on": created_on, + "description": description, + "description_search": description_search, + "ip": ip, + "ip_range_search": ip_range_search, + "ip_search": ip_search, + "modified_on": modified_on, + "page": page, + "per_page": per_page, + "priority": priority, + "uri_search": uri_search, + }, + lockdown_list_params.LockdownListParams, + ), + ), + model=Lockdown, + ) + + async def delete( + self, + lock_downs_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[LockdownDeleteResponse]: + """ + Deletes an existing Zone Lockdown rule. + + Args: + zone_id: Identifier + + lock_downs_id: The unique identifier of the Zone Lockdown rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not lock_downs_id: + raise ValueError(f"Expected a non-empty value for `lock_downs_id` but received {lock_downs_id!r}") + return await self._delete( + f"/zones/{zone_id}/firewall/lockdowns/{lock_downs_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[LockdownDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[LockdownDeleteResponse]], ResultWrapper[LockdownDeleteResponse]), + ) + + async def get( + self, + lock_downs_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Lockdown: + """ + Fetches the details of a Zone Lockdown rule. + + Args: + zone_id: Identifier + + lock_downs_id: The unique identifier of the Zone Lockdown rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not lock_downs_id: + raise ValueError(f"Expected a non-empty value for `lock_downs_id` but received {lock_downs_id!r}") + return await self._get( + f"/zones/{zone_id}/firewall/lockdowns/{lock_downs_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Lockdown]._unwrapper, + ), + cast_to=cast(Type[Lockdown], ResultWrapper[Lockdown]), + ) + + +class LockdownsResourceWithRawResponse: + def __init__(self, lockdowns: LockdownsResource) -> None: + self._lockdowns = lockdowns + + self.create = to_raw_response_wrapper( + lockdowns.create, + ) + self.update = to_raw_response_wrapper( + lockdowns.update, + ) + self.list = to_raw_response_wrapper( + lockdowns.list, + ) + self.delete = to_raw_response_wrapper( + lockdowns.delete, + ) + self.get = to_raw_response_wrapper( + lockdowns.get, + ) + + +class AsyncLockdownsResourceWithRawResponse: + def __init__(self, lockdowns: AsyncLockdownsResource) -> None: + self._lockdowns = lockdowns + + self.create = async_to_raw_response_wrapper( + lockdowns.create, + ) + self.update = async_to_raw_response_wrapper( + lockdowns.update, + ) + self.list = async_to_raw_response_wrapper( + lockdowns.list, + ) + self.delete = async_to_raw_response_wrapper( + lockdowns.delete, + ) + self.get = async_to_raw_response_wrapper( + lockdowns.get, + ) + + +class LockdownsResourceWithStreamingResponse: + def __init__(self, lockdowns: LockdownsResource) -> None: + self._lockdowns = lockdowns + + self.create = to_streamed_response_wrapper( + lockdowns.create, + ) + self.update = to_streamed_response_wrapper( + lockdowns.update, + ) + self.list = to_streamed_response_wrapper( + lockdowns.list, + ) + self.delete = to_streamed_response_wrapper( + lockdowns.delete, + ) + self.get = to_streamed_response_wrapper( + lockdowns.get, + ) + + +class AsyncLockdownsResourceWithStreamingResponse: + def __init__(self, lockdowns: AsyncLockdownsResource) -> None: + self._lockdowns = lockdowns + + self.create = async_to_streamed_response_wrapper( + lockdowns.create, + ) + self.update = async_to_streamed_response_wrapper( + lockdowns.update, + ) + self.list = async_to_streamed_response_wrapper( + lockdowns.list, + ) + self.delete = async_to_streamed_response_wrapper( + lockdowns.delete, + ) + self.get = async_to_streamed_response_wrapper( + lockdowns.get, + ) diff --git a/src/cloudflare/resources/firewall/rules.py b/src/cloudflare/resources/firewall/rules.py new file mode 100644 index 00000000000..0fec41375bd --- /dev/null +++ b/src/cloudflare/resources/firewall/rules.py @@ -0,0 +1,1210 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import typing_extensions +from typing import Type, Optional, cast + +import httpx + +from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ..._utils import ( + maybe_transform, + async_maybe_transform, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._wrappers import ResultWrapper +from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ..._base_client import AsyncPaginator, make_request_options +from ...types.firewall import ( + rule_get_params, + rule_list_params, + rule_create_params, + rule_update_params, + rule_bulk_edit_params, + rule_bulk_update_params, +) +from ...types.firewall.firewall_rule import FirewallRule +from ...types.firewall.rule_edit_response import RuleEditResponse +from ...types.filters.firewall_filter_param import FirewallFilterParam +from ...types.firewall.rule_create_response import RuleCreateResponse +from ...types.firewall.rule_bulk_edit_response import RuleBulkEditResponse +from ...types.firewall.rule_bulk_delete_response import RuleBulkDeleteResponse +from ...types.firewall.rule_bulk_update_response import RuleBulkUpdateResponse + +__all__ = ["RulesResource", "AsyncRulesResource"] + + +class RulesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> RulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return RulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return RulesResourceWithStreamingResponse(self) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def create( + self, + *, + zone_id: str, + action: rule_create_params.Action, + filter: FirewallFilterParam, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleCreateResponse]: + """ + Create one or more firewall rules. + + Args: + zone_id: Identifier + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._post( + f"/zones/{zone_id}/firewall/rules", + body=maybe_transform( + { + "action": action, + "filter": filter, + }, + rule_create_params.RuleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleCreateResponse]], ResultWrapper[RuleCreateResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def update( + self, + rule_id: str, + *, + zone_id: str, + action: rule_update_params.Action, + filter: FirewallFilterParam, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallRule: + """ + Updates an existing firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return self._put( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + body=maybe_transform( + { + "action": action, + "filter": filter, + }, + rule_update_params.RuleUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallRule]._unwrapper, + ), + cast_to=cast(Type[FirewallRule], ResultWrapper[FirewallRule]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def list( + self, + *, + zone_id: str, + id: str | NotGiven = NOT_GIVEN, + action: str | NotGiven = NOT_GIVEN, + description: str | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + paused: bool | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncV4PagePaginationArray[FirewallRule]: + """Fetches firewall rules in a zone. + + You can filter the results using several + optional parameters. + + Args: + zone_id: Identifier + + id: The unique identifier of the firewall rule. + + action: The action to search for. Must be an exact match. + + description: A case-insensitive string to find in the description. + + page: Page number of paginated results. + + paused: When true, indicates that the firewall rule is currently paused. + + per_page: Number of firewall rules per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/rules", + page=SyncV4PagePaginationArray[FirewallRule], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "id": id, + "action": action, + "description": description, + "page": page, + "paused": paused, + "per_page": per_page, + }, + rule_list_params.RuleListParams, + ), + ), + model=FirewallRule, + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def delete( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallRule: + """ + Deletes an existing firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return self._delete( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallRule]._unwrapper, + ), + cast_to=cast(Type[FirewallRule], ResultWrapper[FirewallRule]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def bulk_delete( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleBulkDeleteResponse]: + """ + Deletes existing firewall rules. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._delete( + f"/zones/{zone_id}/firewall/rules", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleBulkDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleBulkDeleteResponse]], ResultWrapper[RuleBulkDeleteResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def bulk_edit( + self, + *, + zone_id: str, + body: object, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleBulkEditResponse]: + """ + Updates the priority of existing firewall rules. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._patch( + f"/zones/{zone_id}/firewall/rules", + body=maybe_transform(body, rule_bulk_edit_params.RuleBulkEditParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleBulkEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleBulkEditResponse]], ResultWrapper[RuleBulkEditResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def bulk_update( + self, + *, + zone_id: str, + body: object, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleBulkUpdateResponse]: + """ + Updates one or more existing firewall rules. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._put( + f"/zones/{zone_id}/firewall/rules", + body=maybe_transform(body, rule_bulk_update_params.RuleBulkUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleBulkUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleBulkUpdateResponse]], ResultWrapper[RuleBulkUpdateResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def edit( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleEditResponse]: + """ + Updates the priority of an existing firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return self._patch( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleEditResponse]], ResultWrapper[RuleEditResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def get( + self, + rule_id: str, + *, + zone_id: str, + id: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallRule: + """ + Fetches the details of a firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + id: The unique identifier of the firewall rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return self._get( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"id": id}, rule_get_params.RuleGetParams), + post_parser=ResultWrapper[FirewallRule]._unwrapper, + ), + cast_to=cast(Type[FirewallRule], ResultWrapper[FirewallRule]), + ) + + +class AsyncRulesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncRulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncRulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncRulesResourceWithStreamingResponse(self) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def create( + self, + *, + zone_id: str, + action: rule_create_params.Action, + filter: FirewallFilterParam, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleCreateResponse]: + """ + Create one or more firewall rules. + + Args: + zone_id: Identifier + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._post( + f"/zones/{zone_id}/firewall/rules", + body=await async_maybe_transform( + { + "action": action, + "filter": filter, + }, + rule_create_params.RuleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleCreateResponse]], ResultWrapper[RuleCreateResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def update( + self, + rule_id: str, + *, + zone_id: str, + action: rule_update_params.Action, + filter: FirewallFilterParam, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallRule: + """ + Updates an existing firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return await self._put( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + body=await async_maybe_transform( + { + "action": action, + "filter": filter, + }, + rule_update_params.RuleUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallRule]._unwrapper, + ), + cast_to=cast(Type[FirewallRule], ResultWrapper[FirewallRule]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + def list( + self, + *, + zone_id: str, + id: str | NotGiven = NOT_GIVEN, + action: str | NotGiven = NOT_GIVEN, + description: str | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + paused: bool | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[FirewallRule, AsyncV4PagePaginationArray[FirewallRule]]: + """Fetches firewall rules in a zone. + + You can filter the results using several + optional parameters. + + Args: + zone_id: Identifier + + id: The unique identifier of the firewall rule. + + action: The action to search for. Must be an exact match. + + description: A case-insensitive string to find in the description. + + page: Page number of paginated results. + + paused: When true, indicates that the firewall rule is currently paused. + + per_page: Number of firewall rules per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/rules", + page=AsyncV4PagePaginationArray[FirewallRule], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "id": id, + "action": action, + "description": description, + "page": page, + "paused": paused, + "per_page": per_page, + }, + rule_list_params.RuleListParams, + ), + ), + model=FirewallRule, + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def delete( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallRule: + """ + Deletes an existing firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return await self._delete( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[FirewallRule]._unwrapper, + ), + cast_to=cast(Type[FirewallRule], ResultWrapper[FirewallRule]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def bulk_delete( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleBulkDeleteResponse]: + """ + Deletes existing firewall rules. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._delete( + f"/zones/{zone_id}/firewall/rules", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleBulkDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleBulkDeleteResponse]], ResultWrapper[RuleBulkDeleteResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def bulk_edit( + self, + *, + zone_id: str, + body: object, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleBulkEditResponse]: + """ + Updates the priority of existing firewall rules. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._patch( + f"/zones/{zone_id}/firewall/rules", + body=await async_maybe_transform(body, rule_bulk_edit_params.RuleBulkEditParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleBulkEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleBulkEditResponse]], ResultWrapper[RuleBulkEditResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def bulk_update( + self, + *, + zone_id: str, + body: object, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleBulkUpdateResponse]: + """ + Updates one or more existing firewall rules. + + Args: + zone_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._put( + f"/zones/{zone_id}/firewall/rules", + body=await async_maybe_transform(body, rule_bulk_update_params.RuleBulkUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleBulkUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleBulkUpdateResponse]], ResultWrapper[RuleBulkUpdateResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def edit( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[RuleEditResponse]: + """ + Updates the priority of an existing firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return await self._patch( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RuleEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RuleEditResponse]], ResultWrapper[RuleEditResponse]), + ) + + @typing_extensions.deprecated( + "The Firewall Rules API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#firewall-rules-api-and-filters-api for full details." + ) + async def get( + self, + rule_id: str, + *, + zone_id: str, + id: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> FirewallRule: + """ + Fetches the details of a firewall rule. + + Args: + zone_id: Identifier + + rule_id: The unique identifier of the firewall rule. + + id: The unique identifier of the firewall rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return await self._get( + f"/zones/{zone_id}/firewall/rules/{rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"id": id}, rule_get_params.RuleGetParams), + post_parser=ResultWrapper[FirewallRule]._unwrapper, + ), + cast_to=cast(Type[FirewallRule], ResultWrapper[FirewallRule]), + ) + + +class RulesResourceWithRawResponse: + def __init__(self, rules: RulesResource) -> None: + self._rules = rules + + self.create = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_edit = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.bulk_edit # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rules.get # pyright: ignore[reportDeprecated], + ) + ) + + +class AsyncRulesResourceWithRawResponse: + def __init__(self, rules: AsyncRulesResource) -> None: + self._rules = rules + + self.create = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_edit = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.bulk_edit # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rules.get # pyright: ignore[reportDeprecated], + ) + ) + + +class RulesResourceWithStreamingResponse: + def __init__(self, rules: RulesResource) -> None: + self._rules = rules + + self.create = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_edit = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.bulk_edit # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rules.get # pyright: ignore[reportDeprecated], + ) + ) + + +class AsyncRulesResourceWithStreamingResponse: + def __init__(self, rules: AsyncRulesResource) -> None: + self._rules = rules + + self.create = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.create # pyright: ignore[reportDeprecated], + ) + ) + self.update = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.update # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_delete = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.bulk_delete # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_edit = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.bulk_edit # pyright: ignore[reportDeprecated], + ) + ) + self.bulk_update = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.bulk_update # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rules.get # pyright: ignore[reportDeprecated], + ) + ) diff --git a/src/cloudflare/resources/firewall/ua_rules.py b/src/cloudflare/resources/firewall/ua_rules.py new file mode 100644 index 00000000000..479799dc555 --- /dev/null +++ b/src/cloudflare/resources/firewall/ua_rules.py @@ -0,0 +1,717 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Any, Type, cast +from typing_extensions import Literal + +import httpx + +from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ..._utils import ( + maybe_transform, + async_maybe_transform, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._wrappers import ResultWrapper +from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ..._base_client import AsyncPaginator, make_request_options +from ...types.firewall import ua_rule_list_params, ua_rule_create_params, ua_rule_update_params +from ...types.firewall.ua_rule_get_response import UARuleGetResponse +from ...types.firewall.ua_rule_list_response import UARuleListResponse +from ...types.firewall.ua_rule_create_response import UARuleCreateResponse +from ...types.firewall.ua_rule_delete_response import UARuleDeleteResponse +from ...types.firewall.ua_rule_update_response import UARuleUpdateResponse + +__all__ = ["UARulesResource", "AsyncUARulesResource"] + + +class UARulesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> UARulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return UARulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> UARulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return UARulesResourceWithStreamingResponse(self) + + def create( + self, + *, + zone_id: str, + configuration: ua_rule_create_params.Configuration, + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleCreateResponse: + """ + Creates a new User Agent Blocking rule in a zone. + + Args: + zone_id: Identifier + + configuration: The rule configuration. + + mode: The action to apply to a matched request. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return cast( + UARuleCreateResponse, + self._post( + f"/zones/{zone_id}/firewall/ua_rules", + body=maybe_transform( + { + "configuration": configuration, + "mode": mode, + }, + ua_rule_create_params.UARuleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[UARuleCreateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def update( + self, + ua_rule_id: str, + *, + zone_id: str, + configuration: ua_rule_update_params.Configuration, + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleUpdateResponse: + """ + Updates an existing User Agent Blocking rule. + + Args: + zone_id: Identifier + + ua_rule_id: The unique identifier of the User Agent Blocking rule. + + configuration: The rule configuration. + + mode: The action to apply to a matched request. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not ua_rule_id: + raise ValueError(f"Expected a non-empty value for `ua_rule_id` but received {ua_rule_id!r}") + return cast( + UARuleUpdateResponse, + self._put( + f"/zones/{zone_id}/firewall/ua_rules/{ua_rule_id}", + body=maybe_transform( + { + "configuration": configuration, + "mode": mode, + }, + ua_rule_update_params.UARuleUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleUpdateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[UARuleUpdateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def list( + self, + *, + zone_id: str, + description: str | NotGiven = NOT_GIVEN, + description_search: str | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + ua_search: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncV4PagePaginationArray[UARuleListResponse]: + """Fetches User Agent Blocking rules in a zone. + + You can filter the results using + several optional parameters. + + Args: + zone_id: Identifier + + description: A string to search for in the description of existing rules. + + description_search: A string to search for in the description of existing rules. + + page: Page number of paginated results. + + per_page: The maximum number of results per page. You can only set the value to `1` or to + a multiple of 5 such as `5`, `10`, `15`, or `20`. + + ua_search: A string to search for in the user agent values of existing rules. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/ua_rules", + page=SyncV4PagePaginationArray[UARuleListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "description": description, + "description_search": description_search, + "page": page, + "per_page": per_page, + "ua_search": ua_search, + }, + ua_rule_list_params.UARuleListParams, + ), + ), + model=UARuleListResponse, + ) + + def delete( + self, + ua_rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleDeleteResponse: + """ + Deletes an existing User Agent Blocking rule. + + Args: + zone_id: Identifier + + ua_rule_id: The unique identifier of the User Agent Blocking rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not ua_rule_id: + raise ValueError(f"Expected a non-empty value for `ua_rule_id` but received {ua_rule_id!r}") + return self._delete( + f"/zones/{zone_id}/firewall/ua_rules/{ua_rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[UARuleDeleteResponse], ResultWrapper[UARuleDeleteResponse]), + ) + + def get( + self, + ua_rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleGetResponse: + """ + Fetches the details of a User Agent Blocking rule. + + Args: + zone_id: Identifier + + ua_rule_id: The unique identifier of the User Agent Blocking rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not ua_rule_id: + raise ValueError(f"Expected a non-empty value for `ua_rule_id` but received {ua_rule_id!r}") + return cast( + UARuleGetResponse, + self._get( + f"/zones/{zone_id}/firewall/ua_rules/{ua_rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[UARuleGetResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class AsyncUARulesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncUARulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncUARulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncUARulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncUARulesResourceWithStreamingResponse(self) + + async def create( + self, + *, + zone_id: str, + configuration: ua_rule_create_params.Configuration, + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleCreateResponse: + """ + Creates a new User Agent Blocking rule in a zone. + + Args: + zone_id: Identifier + + configuration: The rule configuration. + + mode: The action to apply to a matched request. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return cast( + UARuleCreateResponse, + await self._post( + f"/zones/{zone_id}/firewall/ua_rules", + body=await async_maybe_transform( + { + "configuration": configuration, + "mode": mode, + }, + ua_rule_create_params.UARuleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[UARuleCreateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + async def update( + self, + ua_rule_id: str, + *, + zone_id: str, + configuration: ua_rule_update_params.Configuration, + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleUpdateResponse: + """ + Updates an existing User Agent Blocking rule. + + Args: + zone_id: Identifier + + ua_rule_id: The unique identifier of the User Agent Blocking rule. + + configuration: The rule configuration. + + mode: The action to apply to a matched request. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not ua_rule_id: + raise ValueError(f"Expected a non-empty value for `ua_rule_id` but received {ua_rule_id!r}") + return cast( + UARuleUpdateResponse, + await self._put( + f"/zones/{zone_id}/firewall/ua_rules/{ua_rule_id}", + body=await async_maybe_transform( + { + "configuration": configuration, + "mode": mode, + }, + ua_rule_update_params.UARuleUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleUpdateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[UARuleUpdateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def list( + self, + *, + zone_id: str, + description: str | NotGiven = NOT_GIVEN, + description_search: str | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + ua_search: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[UARuleListResponse, AsyncV4PagePaginationArray[UARuleListResponse]]: + """Fetches User Agent Blocking rules in a zone. + + You can filter the results using + several optional parameters. + + Args: + zone_id: Identifier + + description: A string to search for in the description of existing rules. + + description_search: A string to search for in the description of existing rules. + + page: Page number of paginated results. + + per_page: The maximum number of results per page. You can only set the value to `1` or to + a multiple of 5 such as `5`, `10`, `15`, or `20`. + + ua_search: A string to search for in the user agent values of existing rules. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/ua_rules", + page=AsyncV4PagePaginationArray[UARuleListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "description": description, + "description_search": description_search, + "page": page, + "per_page": per_page, + "ua_search": ua_search, + }, + ua_rule_list_params.UARuleListParams, + ), + ), + model=UARuleListResponse, + ) + + async def delete( + self, + ua_rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleDeleteResponse: + """ + Deletes an existing User Agent Blocking rule. + + Args: + zone_id: Identifier + + ua_rule_id: The unique identifier of the User Agent Blocking rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not ua_rule_id: + raise ValueError(f"Expected a non-empty value for `ua_rule_id` but received {ua_rule_id!r}") + return await self._delete( + f"/zones/{zone_id}/firewall/ua_rules/{ua_rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[UARuleDeleteResponse], ResultWrapper[UARuleDeleteResponse]), + ) + + async def get( + self, + ua_rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> UARuleGetResponse: + """ + Fetches the details of a User Agent Blocking rule. + + Args: + zone_id: Identifier + + ua_rule_id: The unique identifier of the User Agent Blocking rule. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not ua_rule_id: + raise ValueError(f"Expected a non-empty value for `ua_rule_id` but received {ua_rule_id!r}") + return cast( + UARuleGetResponse, + await self._get( + f"/zones/{zone_id}/firewall/ua_rules/{ua_rule_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[UARuleGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[UARuleGetResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class UARulesResourceWithRawResponse: + def __init__(self, ua_rules: UARulesResource) -> None: + self._ua_rules = ua_rules + + self.create = to_raw_response_wrapper( + ua_rules.create, + ) + self.update = to_raw_response_wrapper( + ua_rules.update, + ) + self.list = to_raw_response_wrapper( + ua_rules.list, + ) + self.delete = to_raw_response_wrapper( + ua_rules.delete, + ) + self.get = to_raw_response_wrapper( + ua_rules.get, + ) + + +class AsyncUARulesResourceWithRawResponse: + def __init__(self, ua_rules: AsyncUARulesResource) -> None: + self._ua_rules = ua_rules + + self.create = async_to_raw_response_wrapper( + ua_rules.create, + ) + self.update = async_to_raw_response_wrapper( + ua_rules.update, + ) + self.list = async_to_raw_response_wrapper( + ua_rules.list, + ) + self.delete = async_to_raw_response_wrapper( + ua_rules.delete, + ) + self.get = async_to_raw_response_wrapper( + ua_rules.get, + ) + + +class UARulesResourceWithStreamingResponse: + def __init__(self, ua_rules: UARulesResource) -> None: + self._ua_rules = ua_rules + + self.create = to_streamed_response_wrapper( + ua_rules.create, + ) + self.update = to_streamed_response_wrapper( + ua_rules.update, + ) + self.list = to_streamed_response_wrapper( + ua_rules.list, + ) + self.delete = to_streamed_response_wrapper( + ua_rules.delete, + ) + self.get = to_streamed_response_wrapper( + ua_rules.get, + ) + + +class AsyncUARulesResourceWithStreamingResponse: + def __init__(self, ua_rules: AsyncUARulesResource) -> None: + self._ua_rules = ua_rules + + self.create = async_to_streamed_response_wrapper( + ua_rules.create, + ) + self.update = async_to_streamed_response_wrapper( + ua_rules.update, + ) + self.list = async_to_streamed_response_wrapper( + ua_rules.list, + ) + self.delete = async_to_streamed_response_wrapper( + ua_rules.delete, + ) + self.get = async_to_streamed_response_wrapper( + ua_rules.get, + ) diff --git a/src/cloudflare/resources/firewall/waf/__init__.py b/src/cloudflare/resources/firewall/waf/__init__.py index 0a8c544fa65..03886bfc2c7 100644 --- a/src/cloudflare/resources/firewall/waf/__init__.py +++ b/src/cloudflare/resources/firewall/waf/__init__.py @@ -16,8 +16,22 @@ PackagesResourceWithStreamingResponse, AsyncPackagesResourceWithStreamingResponse, ) +from .overrides import ( + OverridesResource, + AsyncOverridesResource, + OverridesResourceWithRawResponse, + AsyncOverridesResourceWithRawResponse, + OverridesResourceWithStreamingResponse, + AsyncOverridesResourceWithStreamingResponse, +) __all__ = [ + "OverridesResource", + "AsyncOverridesResource", + "OverridesResourceWithRawResponse", + "AsyncOverridesResourceWithRawResponse", + "OverridesResourceWithStreamingResponse", + "AsyncOverridesResourceWithStreamingResponse", "PackagesResource", "AsyncPackagesResource", "PackagesResourceWithRawResponse", diff --git a/src/cloudflare/resources/firewall/waf/overrides.py b/src/cloudflare/resources/firewall/waf/overrides.py new file mode 100644 index 00000000000..b7c1fb54be7 --- /dev/null +++ b/src/cloudflare/resources/firewall/waf/overrides.py @@ -0,0 +1,706 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Type, Optional, cast + +import httpx + +from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ...._utils import ( + maybe_transform, + async_maybe_transform, +) +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ...._base_client import AsyncPaginator, make_request_options +from ....types.firewall.waf import ( + override_list_params, + override_create_params, + override_update_params, +) +from ....types.firewall.waf.override import Override +from ....types.firewall.waf.override_url import OverrideURL +from ....types.firewall.waf.waf_rule_param import WAFRuleParam +from ....types.firewall.waf.rewrite_action_param import RewriteActionParam +from ....types.firewall.waf.override_delete_response import OverrideDeleteResponse + +__all__ = ["OverridesResource", "AsyncOverridesResource"] + + +class OverridesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> OverridesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return OverridesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> OverridesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return OverridesResourceWithStreamingResponse(self) + + def create( + self, + *, + zone_id: str, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Override: + """ + Creates a URI-based WAF override for a zone. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._post( + f"/zones/{zone_id}/firewall/waf/overrides", + body=maybe_transform({"urls": urls}, override_create_params.OverrideCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Override]._unwrapper, + ), + cast_to=cast(Type[Override], ResultWrapper[Override]), + ) + + def update( + self, + overrides_id: str, + *, + zone_id: str, + id: str, + rewrite_action: RewriteActionParam, + rules: WAFRuleParam, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Override: + """ + Updates an existing URI-based WAF override. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + overrides_id: The unique identifier of the WAF override. + + id: Identifier + + rewrite_action: Specifies that, when a WAF rule matches, its configured action will be replaced + by the action configured in this object. + + rules: An object that allows you to override the action of specific WAF rules. Each key + of this object must be the ID of a WAF rule, and each value must be a valid WAF + action. Unless you are disabling a rule, ensure that you also enable the rule + group that this WAF rule belongs to. When creating a new URI-based WAF override, + you must provide a `groups` object or a `rules` object. + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not overrides_id: + raise ValueError(f"Expected a non-empty value for `overrides_id` but received {overrides_id!r}") + return self._put( + f"/zones/{zone_id}/firewall/waf/overrides/{overrides_id}", + body=maybe_transform( + { + "id": id, + "rewrite_action": rewrite_action, + "rules": rules, + "urls": urls, + }, + override_update_params.OverrideUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Override]._unwrapper, + ), + cast_to=cast(Type[Override], ResultWrapper[Override]), + ) + + def list( + self, + *, + zone_id: str, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncV4PagePaginationArray[Override]: + """ + Fetches the URI-based WAF overrides in a zone. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + page: The page number of paginated results. + + per_page: The number of WAF overrides per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/waf/overrides", + page=SyncV4PagePaginationArray[Override], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + override_list_params.OverrideListParams, + ), + ), + model=Override, + ) + + def delete( + self, + overrides_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[OverrideDeleteResponse]: + """ + Deletes an existing URI-based WAF override. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + overrides_id: The unique identifier of the WAF override. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not overrides_id: + raise ValueError(f"Expected a non-empty value for `overrides_id` but received {overrides_id!r}") + return self._delete( + f"/zones/{zone_id}/firewall/waf/overrides/{overrides_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[OverrideDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[OverrideDeleteResponse]], ResultWrapper[OverrideDeleteResponse]), + ) + + def get( + self, + overrides_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Override: + """ + Fetches the details of a URI-based WAF override. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + overrides_id: The unique identifier of the WAF override. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not overrides_id: + raise ValueError(f"Expected a non-empty value for `overrides_id` but received {overrides_id!r}") + return self._get( + f"/zones/{zone_id}/firewall/waf/overrides/{overrides_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Override]._unwrapper, + ), + cast_to=cast(Type[Override], ResultWrapper[Override]), + ) + + +class AsyncOverridesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncOverridesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncOverridesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncOverridesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncOverridesResourceWithStreamingResponse(self) + + async def create( + self, + *, + zone_id: str, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Override: + """ + Creates a URI-based WAF override for a zone. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._post( + f"/zones/{zone_id}/firewall/waf/overrides", + body=await async_maybe_transform({"urls": urls}, override_create_params.OverrideCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Override]._unwrapper, + ), + cast_to=cast(Type[Override], ResultWrapper[Override]), + ) + + async def update( + self, + overrides_id: str, + *, + zone_id: str, + id: str, + rewrite_action: RewriteActionParam, + rules: WAFRuleParam, + urls: List[OverrideURL], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Override: + """ + Updates an existing URI-based WAF override. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + overrides_id: The unique identifier of the WAF override. + + id: Identifier + + rewrite_action: Specifies that, when a WAF rule matches, its configured action will be replaced + by the action configured in this object. + + rules: An object that allows you to override the action of specific WAF rules. Each key + of this object must be the ID of a WAF rule, and each value must be a valid WAF + action. Unless you are disabling a rule, ensure that you also enable the rule + group that this WAF rule belongs to. When creating a new URI-based WAF override, + you must provide a `groups` object or a `rules` object. + + urls: The URLs to include in the current WAF override. You can use wildcards. Each + entered URL will be escaped before use, which means you can only use simple + wildcard patterns. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not overrides_id: + raise ValueError(f"Expected a non-empty value for `overrides_id` but received {overrides_id!r}") + return await self._put( + f"/zones/{zone_id}/firewall/waf/overrides/{overrides_id}", + body=await async_maybe_transform( + { + "id": id, + "rewrite_action": rewrite_action, + "rules": rules, + "urls": urls, + }, + override_update_params.OverrideUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Override]._unwrapper, + ), + cast_to=cast(Type[Override], ResultWrapper[Override]), + ) + + def list( + self, + *, + zone_id: str, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[Override, AsyncV4PagePaginationArray[Override]]: + """ + Fetches the URI-based WAF overrides in a zone. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + page: The page number of paginated results. + + per_page: The number of WAF overrides per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/waf/overrides", + page=AsyncV4PagePaginationArray[Override], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + override_list_params.OverrideListParams, + ), + ), + model=Override, + ) + + async def delete( + self, + overrides_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Optional[OverrideDeleteResponse]: + """ + Deletes an existing URI-based WAF override. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + overrides_id: The unique identifier of the WAF override. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not overrides_id: + raise ValueError(f"Expected a non-empty value for `overrides_id` but received {overrides_id!r}") + return await self._delete( + f"/zones/{zone_id}/firewall/waf/overrides/{overrides_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[OverrideDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[OverrideDeleteResponse]], ResultWrapper[OverrideDeleteResponse]), + ) + + async def get( + self, + overrides_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> Override: + """ + Fetches the details of a URI-based WAF override. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + overrides_id: The unique identifier of the WAF override. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not overrides_id: + raise ValueError(f"Expected a non-empty value for `overrides_id` but received {overrides_id!r}") + return await self._get( + f"/zones/{zone_id}/firewall/waf/overrides/{overrides_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Override]._unwrapper, + ), + cast_to=cast(Type[Override], ResultWrapper[Override]), + ) + + +class OverridesResourceWithRawResponse: + def __init__(self, overrides: OverridesResource) -> None: + self._overrides = overrides + + self.create = to_raw_response_wrapper( + overrides.create, + ) + self.update = to_raw_response_wrapper( + overrides.update, + ) + self.list = to_raw_response_wrapper( + overrides.list, + ) + self.delete = to_raw_response_wrapper( + overrides.delete, + ) + self.get = to_raw_response_wrapper( + overrides.get, + ) + + +class AsyncOverridesResourceWithRawResponse: + def __init__(self, overrides: AsyncOverridesResource) -> None: + self._overrides = overrides + + self.create = async_to_raw_response_wrapper( + overrides.create, + ) + self.update = async_to_raw_response_wrapper( + overrides.update, + ) + self.list = async_to_raw_response_wrapper( + overrides.list, + ) + self.delete = async_to_raw_response_wrapper( + overrides.delete, + ) + self.get = async_to_raw_response_wrapper( + overrides.get, + ) + + +class OverridesResourceWithStreamingResponse: + def __init__(self, overrides: OverridesResource) -> None: + self._overrides = overrides + + self.create = to_streamed_response_wrapper( + overrides.create, + ) + self.update = to_streamed_response_wrapper( + overrides.update, + ) + self.list = to_streamed_response_wrapper( + overrides.list, + ) + self.delete = to_streamed_response_wrapper( + overrides.delete, + ) + self.get = to_streamed_response_wrapper( + overrides.get, + ) + + +class AsyncOverridesResourceWithStreamingResponse: + def __init__(self, overrides: AsyncOverridesResource) -> None: + self._overrides = overrides + + self.create = async_to_streamed_response_wrapper( + overrides.create, + ) + self.update = async_to_streamed_response_wrapper( + overrides.update, + ) + self.list = async_to_streamed_response_wrapper( + overrides.list, + ) + self.delete = async_to_streamed_response_wrapper( + overrides.delete, + ) + self.get = async_to_streamed_response_wrapper( + overrides.get, + ) diff --git a/src/cloudflare/resources/firewall/waf/packages/packages.py b/src/cloudflare/resources/firewall/waf/packages/packages.py index fc04985529c..fcbc3cbbba8 100644 --- a/src/cloudflare/resources/firewall/waf/packages/packages.py +++ b/src/cloudflare/resources/firewall/waf/packages/packages.py @@ -2,6 +2,11 @@ from __future__ import annotations +from typing import Any, cast +from typing_extensions import Literal + +import httpx + from .rules import ( RulesResource, AsyncRulesResource, @@ -18,8 +23,20 @@ GroupsResourceWithStreamingResponse, AsyncGroupsResourceWithStreamingResponse, ) +from ....._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ....._utils import maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ....._base_client import AsyncPaginator, make_request_options +from .....types.firewall.waf import package_list_params +from .....types.firewall.waf.package_get_response import PackageGetResponse __all__ = ["PackagesResource", "AsyncPackagesResource"] @@ -52,6 +69,126 @@ def with_streaming_response(self) -> PackagesResourceWithStreamingResponse: """ return PackagesResourceWithStreamingResponse(self) + def list( + self, + *, + zone_id: str, + direction: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + match: Literal["any", "all"] | NotGiven = NOT_GIVEN, + name: str | NotGiven = NOT_GIVEN, + order: Literal["name"] | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncV4PagePaginationArray[object]: + """ + Fetches WAF packages for a zone. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + direction: The direction used to sort returned packages. + + match: When set to `all`, all the search requirements must match. When set to `any`, + only one of the search requirements has to match. + + name: The name of the WAF package. + + order: The field used to sort returned packages. + + page: The page number of paginated results. + + per_page: The number of packages per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/waf/packages", + page=SyncV4PagePaginationArray[object], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "direction": direction, + "match": match, + "name": name, + "order": order, + "page": page, + "per_page": per_page, + }, + package_list_params.PackageListParams, + ), + ), + model=object, + ) + + def get( + self, + package_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> PackageGetResponse: + """ + Fetches the details of a WAF package. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + package_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not package_id: + raise ValueError(f"Expected a non-empty value for `package_id` but received {package_id!r}") + return cast( + PackageGetResponse, + self._get( + f"/zones/{zone_id}/firewall/waf/packages/{package_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, PackageGetResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + class AsyncPackagesResource(AsyncAPIResource): @cached_property @@ -81,11 +218,138 @@ def with_streaming_response(self) -> AsyncPackagesResourceWithStreamingResponse: """ return AsyncPackagesResourceWithStreamingResponse(self) + def list( + self, + *, + zone_id: str, + direction: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + match: Literal["any", "all"] | NotGiven = NOT_GIVEN, + name: str | NotGiven = NOT_GIVEN, + order: Literal["name"] | NotGiven = NOT_GIVEN, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[object, AsyncV4PagePaginationArray[object]]: + """ + Fetches WAF packages for a zone. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + direction: The direction used to sort returned packages. + + match: When set to `all`, all the search requirements must match. When set to `any`, + only one of the search requirements has to match. + + name: The name of the WAF package. + + order: The field used to sort returned packages. + + page: The page number of paginated results. + + per_page: The number of packages per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/firewall/waf/packages", + page=AsyncV4PagePaginationArray[object], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "direction": direction, + "match": match, + "name": name, + "order": order, + "page": page, + "per_page": per_page, + }, + package_list_params.PackageListParams, + ), + ), + model=object, + ) + + async def get( + self, + package_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> PackageGetResponse: + """ + Fetches the details of a WAF package. + + **Note:** Applies only to the + [previous version of WAF managed rules](https://developers.cloudflare.com/support/firewall/managed-rules-web-application-firewall-waf/understanding-waf-managed-rules-web-application-firewall/). + + Args: + zone_id: Identifier + + package_id: Identifier + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not package_id: + raise ValueError(f"Expected a non-empty value for `package_id` but received {package_id!r}") + return cast( + PackageGetResponse, + await self._get( + f"/zones/{zone_id}/firewall/waf/packages/{package_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast( + Any, PackageGetResponse + ), # Union types cannot be passed in as arguments in the type system + ), + ) + class PackagesResourceWithRawResponse: def __init__(self, packages: PackagesResource) -> None: self._packages = packages + self.list = to_raw_response_wrapper( + packages.list, + ) + self.get = to_raw_response_wrapper( + packages.get, + ) + @cached_property def groups(self) -> GroupsResourceWithRawResponse: return GroupsResourceWithRawResponse(self._packages.groups) @@ -99,6 +363,13 @@ class AsyncPackagesResourceWithRawResponse: def __init__(self, packages: AsyncPackagesResource) -> None: self._packages = packages + self.list = async_to_raw_response_wrapper( + packages.list, + ) + self.get = async_to_raw_response_wrapper( + packages.get, + ) + @cached_property def groups(self) -> AsyncGroupsResourceWithRawResponse: return AsyncGroupsResourceWithRawResponse(self._packages.groups) @@ -112,6 +383,13 @@ class PackagesResourceWithStreamingResponse: def __init__(self, packages: PackagesResource) -> None: self._packages = packages + self.list = to_streamed_response_wrapper( + packages.list, + ) + self.get = to_streamed_response_wrapper( + packages.get, + ) + @cached_property def groups(self) -> GroupsResourceWithStreamingResponse: return GroupsResourceWithStreamingResponse(self._packages.groups) @@ -125,6 +403,13 @@ class AsyncPackagesResourceWithStreamingResponse: def __init__(self, packages: AsyncPackagesResource) -> None: self._packages = packages + self.list = async_to_streamed_response_wrapper( + packages.list, + ) + self.get = async_to_streamed_response_wrapper( + packages.get, + ) + @cached_property def groups(self) -> AsyncGroupsResourceWithStreamingResponse: return AsyncGroupsResourceWithStreamingResponse(self._packages.groups) diff --git a/src/cloudflare/resources/firewall/waf/waf.py b/src/cloudflare/resources/firewall/waf/waf.py index 42778b033ee..12d89bef38b 100644 --- a/src/cloudflare/resources/firewall/waf/waf.py +++ b/src/cloudflare/resources/firewall/waf/waf.py @@ -10,6 +10,14 @@ PackagesResourceWithStreamingResponse, AsyncPackagesResourceWithStreamingResponse, ) +from .overrides import ( + OverridesResource, + AsyncOverridesResource, + OverridesResourceWithRawResponse, + AsyncOverridesResourceWithRawResponse, + OverridesResourceWithStreamingResponse, + AsyncOverridesResourceWithStreamingResponse, +) from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from .packages.packages import PackagesResource, AsyncPackagesResource @@ -18,6 +26,10 @@ class WAFResource(SyncAPIResource): + @cached_property + def overrides(self) -> OverridesResource: + return OverridesResource(self._client) + @cached_property def packages(self) -> PackagesResource: return PackagesResource(self._client) @@ -43,6 +55,10 @@ def with_streaming_response(self) -> WAFResourceWithStreamingResponse: class AsyncWAFResource(AsyncAPIResource): + @cached_property + def overrides(self) -> AsyncOverridesResource: + return AsyncOverridesResource(self._client) + @cached_property def packages(self) -> AsyncPackagesResource: return AsyncPackagesResource(self._client) @@ -71,6 +87,10 @@ class WAFResourceWithRawResponse: def __init__(self, waf: WAFResource) -> None: self._waf = waf + @cached_property + def overrides(self) -> OverridesResourceWithRawResponse: + return OverridesResourceWithRawResponse(self._waf.overrides) + @cached_property def packages(self) -> PackagesResourceWithRawResponse: return PackagesResourceWithRawResponse(self._waf.packages) @@ -80,6 +100,10 @@ class AsyncWAFResourceWithRawResponse: def __init__(self, waf: AsyncWAFResource) -> None: self._waf = waf + @cached_property + def overrides(self) -> AsyncOverridesResourceWithRawResponse: + return AsyncOverridesResourceWithRawResponse(self._waf.overrides) + @cached_property def packages(self) -> AsyncPackagesResourceWithRawResponse: return AsyncPackagesResourceWithRawResponse(self._waf.packages) @@ -89,6 +113,10 @@ class WAFResourceWithStreamingResponse: def __init__(self, waf: WAFResource) -> None: self._waf = waf + @cached_property + def overrides(self) -> OverridesResourceWithStreamingResponse: + return OverridesResourceWithStreamingResponse(self._waf.overrides) + @cached_property def packages(self) -> PackagesResourceWithStreamingResponse: return PackagesResourceWithStreamingResponse(self._waf.packages) @@ -98,6 +126,10 @@ class AsyncWAFResourceWithStreamingResponse: def __init__(self, waf: AsyncWAFResource) -> None: self._waf = waf + @cached_property + def overrides(self) -> AsyncOverridesResourceWithStreamingResponse: + return AsyncOverridesResourceWithStreamingResponse(self._waf.overrides) + @cached_property def packages(self) -> AsyncPackagesResourceWithStreamingResponse: return AsyncPackagesResourceWithStreamingResponse(self._waf.packages) diff --git a/src/cloudflare/resources/pagerules/pagerules.py b/src/cloudflare/resources/pagerules.py similarity index 78% rename from src/cloudflare/resources/pagerules/pagerules.py rename to src/cloudflare/resources/pagerules.py index 7bfa3204cfe..3297f84978a 100644 --- a/src/cloudflare/resources/pagerules/pagerules.py +++ b/src/cloudflare/resources/pagerules.py @@ -2,54 +2,36 @@ from __future__ import annotations -import typing_extensions from typing import Type, Iterable, Optional, cast from typing_extensions import Literal import httpx -from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from ..._utils import ( +from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from .._utils import ( maybe_transform, async_maybe_transform, ) -from .settings import ( - SettingsResource, - AsyncSettingsResource, - SettingsResourceWithRawResponse, - AsyncSettingsResourceWithRawResponse, - SettingsResourceWithStreamingResponse, - AsyncSettingsResourceWithStreamingResponse, -) -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( to_raw_response_wrapper, to_streamed_response_wrapper, async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ..._wrappers import ResultWrapper -from ..._base_client import make_request_options -from ...types.pagerules import ( - pagerule_edit_params, - pagerule_list_params, - pagerule_create_params, - pagerule_update_params, -) -from ...types.pagerules.page_rule import PageRule -from ...types.pagerules.target_param import TargetParam -from ...types.pagerules.pagerule_list_response import PageruleListResponse -from ...types.pagerules.pagerule_delete_response import PageruleDeleteResponse +from .._wrappers import ResultWrapper +from .._base_client import make_request_options +from ..types.pagerules import pagerule_edit_params, pagerule_list_params, pagerule_create_params, pagerule_update_params +from ..types.pagerules.page_rule import PageRule +from ..types.pagerules.target_param import TargetParam +from ..types.pagerules.pagerule_list_response import PageruleListResponse +from ..types.pagerules.pagerule_delete_response import PageruleDeleteResponse __all__ = ["PagerulesResource", "AsyncPagerulesResource"] class PagerulesResource(SyncAPIResource): - @cached_property - def settings(self) -> SettingsResource: - return SettingsResource(self._client) - @cached_property def with_raw_response(self) -> PagerulesResourceWithRawResponse: """ @@ -69,9 +51,6 @@ def with_streaming_response(self) -> PagerulesResourceWithStreamingResponse: """ return PagerulesResourceWithStreamingResponse(self) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) def create( self, *, @@ -137,9 +116,6 @@ def create( cast_to=cast(Type[Optional[PageRule]], ResultWrapper[PageRule]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) def update( self, pagerule_id: str, @@ -212,9 +188,6 @@ def update( cast_to=cast(Type[Optional[PageRule]], ResultWrapper[PageRule]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) def list( self, *, @@ -276,9 +249,6 @@ def list( cast_to=cast(Type[Optional[PageruleListResponse]], ResultWrapper[PageruleListResponse]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) def delete( self, pagerule_id: str, @@ -323,9 +293,6 @@ def delete( cast_to=cast(Type[Optional[PageruleDeleteResponse]], ResultWrapper[PageruleDeleteResponse]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) def edit( self, pagerule_id: str, @@ -396,9 +363,6 @@ def edit( cast_to=cast(Type[Optional[PageRule]], ResultWrapper[PageRule]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) def get( self, pagerule_id: str, @@ -445,10 +409,6 @@ def get( class AsyncPagerulesResource(AsyncAPIResource): - @cached_property - def settings(self) -> AsyncSettingsResource: - return AsyncSettingsResource(self._client) - @cached_property def with_raw_response(self) -> AsyncPagerulesResourceWithRawResponse: """ @@ -468,9 +428,6 @@ def with_streaming_response(self) -> AsyncPagerulesResourceWithStreamingResponse """ return AsyncPagerulesResourceWithStreamingResponse(self) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) async def create( self, *, @@ -536,9 +493,6 @@ async def create( cast_to=cast(Type[Optional[PageRule]], ResultWrapper[PageRule]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) async def update( self, pagerule_id: str, @@ -611,9 +565,6 @@ async def update( cast_to=cast(Type[Optional[PageRule]], ResultWrapper[PageRule]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) async def list( self, *, @@ -675,9 +626,6 @@ async def list( cast_to=cast(Type[Optional[PageruleListResponse]], ResultWrapper[PageruleListResponse]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) async def delete( self, pagerule_id: str, @@ -722,9 +670,6 @@ async def delete( cast_to=cast(Type[Optional[PageruleDeleteResponse]], ResultWrapper[PageruleDeleteResponse]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) async def edit( self, pagerule_id: str, @@ -795,9 +740,6 @@ async def edit( cast_to=cast(Type[Optional[PageRule]], ResultWrapper[PageRule]), ) - @typing_extensions.deprecated( - "The Page Rules API is deprecated in favour of the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#page-rules for full details." - ) async def get( self, pagerule_id: str, @@ -847,157 +789,93 @@ class PagerulesResourceWithRawResponse: def __init__(self, pagerules: PagerulesResource) -> None: self._pagerules = pagerules - self.create = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - pagerules.create # pyright: ignore[reportDeprecated], - ) + self.create = to_raw_response_wrapper( + pagerules.create, ) - self.update = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - pagerules.update # pyright: ignore[reportDeprecated], - ) + self.update = to_raw_response_wrapper( + pagerules.update, ) - self.list = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - pagerules.list # pyright: ignore[reportDeprecated], - ) + self.list = to_raw_response_wrapper( + pagerules.list, ) - self.delete = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - pagerules.delete # pyright: ignore[reportDeprecated], - ) + self.delete = to_raw_response_wrapper( + pagerules.delete, ) - self.edit = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - pagerules.edit # pyright: ignore[reportDeprecated], - ) + self.edit = to_raw_response_wrapper( + pagerules.edit, ) - self.get = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - pagerules.get # pyright: ignore[reportDeprecated], - ) + self.get = to_raw_response_wrapper( + pagerules.get, ) - @cached_property - def settings(self) -> SettingsResourceWithRawResponse: - return SettingsResourceWithRawResponse(self._pagerules.settings) - class AsyncPagerulesResourceWithRawResponse: def __init__(self, pagerules: AsyncPagerulesResource) -> None: self._pagerules = pagerules - self.create = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - pagerules.create # pyright: ignore[reportDeprecated], - ) + self.create = async_to_raw_response_wrapper( + pagerules.create, ) - self.update = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - pagerules.update # pyright: ignore[reportDeprecated], - ) + self.update = async_to_raw_response_wrapper( + pagerules.update, ) - self.list = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - pagerules.list # pyright: ignore[reportDeprecated], - ) + self.list = async_to_raw_response_wrapper( + pagerules.list, ) - self.delete = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - pagerules.delete # pyright: ignore[reportDeprecated], - ) + self.delete = async_to_raw_response_wrapper( + pagerules.delete, ) - self.edit = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - pagerules.edit # pyright: ignore[reportDeprecated], - ) + self.edit = async_to_raw_response_wrapper( + pagerules.edit, ) - self.get = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - pagerules.get # pyright: ignore[reportDeprecated], - ) + self.get = async_to_raw_response_wrapper( + pagerules.get, ) - @cached_property - def settings(self) -> AsyncSettingsResourceWithRawResponse: - return AsyncSettingsResourceWithRawResponse(self._pagerules.settings) - class PagerulesResourceWithStreamingResponse: def __init__(self, pagerules: PagerulesResource) -> None: self._pagerules = pagerules - self.create = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - pagerules.create # pyright: ignore[reportDeprecated], - ) + self.create = to_streamed_response_wrapper( + pagerules.create, ) - self.update = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - pagerules.update # pyright: ignore[reportDeprecated], - ) + self.update = to_streamed_response_wrapper( + pagerules.update, ) - self.list = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - pagerules.list # pyright: ignore[reportDeprecated], - ) + self.list = to_streamed_response_wrapper( + pagerules.list, ) - self.delete = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - pagerules.delete # pyright: ignore[reportDeprecated], - ) + self.delete = to_streamed_response_wrapper( + pagerules.delete, ) - self.edit = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - pagerules.edit # pyright: ignore[reportDeprecated], - ) + self.edit = to_streamed_response_wrapper( + pagerules.edit, ) - self.get = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - pagerules.get # pyright: ignore[reportDeprecated], - ) + self.get = to_streamed_response_wrapper( + pagerules.get, ) - @cached_property - def settings(self) -> SettingsResourceWithStreamingResponse: - return SettingsResourceWithStreamingResponse(self._pagerules.settings) - class AsyncPagerulesResourceWithStreamingResponse: def __init__(self, pagerules: AsyncPagerulesResource) -> None: self._pagerules = pagerules - self.create = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - pagerules.create # pyright: ignore[reportDeprecated], - ) + self.create = async_to_streamed_response_wrapper( + pagerules.create, ) - self.update = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - pagerules.update # pyright: ignore[reportDeprecated], - ) + self.update = async_to_streamed_response_wrapper( + pagerules.update, ) - self.list = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - pagerules.list # pyright: ignore[reportDeprecated], - ) + self.list = async_to_streamed_response_wrapper( + pagerules.list, ) - self.delete = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - pagerules.delete # pyright: ignore[reportDeprecated], - ) + self.delete = async_to_streamed_response_wrapper( + pagerules.delete, ) - self.edit = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - pagerules.edit # pyright: ignore[reportDeprecated], - ) + self.edit = async_to_streamed_response_wrapper( + pagerules.edit, ) - self.get = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - pagerules.get # pyright: ignore[reportDeprecated], - ) + self.get = async_to_streamed_response_wrapper( + pagerules.get, ) - - @cached_property - def settings(self) -> AsyncSettingsResourceWithStreamingResponse: - return AsyncSettingsResourceWithStreamingResponse(self._pagerules.settings) diff --git a/src/cloudflare/resources/pagerules/__init__.py b/src/cloudflare/resources/pagerules/__init__.py deleted file mode 100644 index d1c6434816b..00000000000 --- a/src/cloudflare/resources/pagerules/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .settings import ( - SettingsResource, - AsyncSettingsResource, - SettingsResourceWithRawResponse, - AsyncSettingsResourceWithRawResponse, - SettingsResourceWithStreamingResponse, - AsyncSettingsResourceWithStreamingResponse, -) -from .pagerules import ( - PagerulesResource, - AsyncPagerulesResource, - PagerulesResourceWithRawResponse, - AsyncPagerulesResourceWithRawResponse, - PagerulesResourceWithStreamingResponse, - AsyncPagerulesResourceWithStreamingResponse, -) - -__all__ = [ - "SettingsResource", - "AsyncSettingsResource", - "SettingsResourceWithRawResponse", - "AsyncSettingsResourceWithRawResponse", - "SettingsResourceWithStreamingResponse", - "AsyncSettingsResourceWithStreamingResponse", - "PagerulesResource", - "AsyncPagerulesResource", - "PagerulesResourceWithRawResponse", - "AsyncPagerulesResourceWithRawResponse", - "PagerulesResourceWithStreamingResponse", - "AsyncPagerulesResourceWithStreamingResponse", -] diff --git a/src/cloudflare/resources/pagerules/settings.py b/src/cloudflare/resources/pagerules/settings.py deleted file mode 100644 index bd598cff9db..00000000000 --- a/src/cloudflare/resources/pagerules/settings.py +++ /dev/null @@ -1,180 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, Optional, cast - -import httpx - -from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from ..._base_client import make_request_options -from ...types.pagerules.setting_list_response import SettingListResponse - -__all__ = ["SettingsResource", "AsyncSettingsResource"] - - -class SettingsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> SettingsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return the - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return SettingsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> SettingsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return SettingsResourceWithStreamingResponse(self) - - def list( - self, - *, - zone_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> Optional[SettingListResponse]: - """ - Returns a list of settings (and their details) that Page Rules can apply to - matching requests. - - Args: - zone_id: Identifier - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not zone_id: - raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return self._get( - f"/zones/{zone_id}/pagerules/settings", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[SettingListResponse]]._unwrapper, - ), - cast_to=cast(Type[Optional[SettingListResponse]], ResultWrapper[SettingListResponse]), - ) - - -class AsyncSettingsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncSettingsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return the - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncSettingsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncSettingsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncSettingsResourceWithStreamingResponse(self) - - async def list( - self, - *, - zone_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> Optional[SettingListResponse]: - """ - Returns a list of settings (and their details) that Page Rules can apply to - matching requests. - - Args: - zone_id: Identifier - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not zone_id: - raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return await self._get( - f"/zones/{zone_id}/pagerules/settings", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[SettingListResponse]]._unwrapper, - ), - cast_to=cast(Type[Optional[SettingListResponse]], ResultWrapper[SettingListResponse]), - ) - - -class SettingsResourceWithRawResponse: - def __init__(self, settings: SettingsResource) -> None: - self._settings = settings - - self.list = to_raw_response_wrapper( - settings.list, - ) - - -class AsyncSettingsResourceWithRawResponse: - def __init__(self, settings: AsyncSettingsResource) -> None: - self._settings = settings - - self.list = async_to_raw_response_wrapper( - settings.list, - ) - - -class SettingsResourceWithStreamingResponse: - def __init__(self, settings: SettingsResource) -> None: - self._settings = settings - - self.list = to_streamed_response_wrapper( - settings.list, - ) - - -class AsyncSettingsResourceWithStreamingResponse: - def __init__(self, settings: AsyncSettingsResource) -> None: - self._settings = settings - - self.list = async_to_streamed_response_wrapper( - settings.list, - ) diff --git a/src/cloudflare/resources/rate_limits.py b/src/cloudflare/resources/rate_limits.py new file mode 100644 index 00000000000..131285b95af --- /dev/null +++ b/src/cloudflare/resources/rate_limits.py @@ -0,0 +1,778 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import typing_extensions +from typing import Type, cast + +import httpx + +from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from .._utils import ( + maybe_transform, + async_maybe_transform, +) +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._wrappers import ResultWrapper +from ..pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from .._base_client import AsyncPaginator, make_request_options +from ..types.rate_limits import rate_limit_edit_params, rate_limit_list_params, rate_limit_create_params +from ..types.rate_limits.rate_limit import RateLimit +from ..types.rate_limits.rate_limit_delete_response import RateLimitDeleteResponse + +__all__ = ["RateLimitsResource", "AsyncRateLimitsResource"] + + +class RateLimitsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> RateLimitsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return RateLimitsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RateLimitsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return RateLimitsResourceWithStreamingResponse(self) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + def create( + self, + *, + zone_id: str, + action: rate_limit_create_params.Action, + match: rate_limit_create_params.Match, + period: float, + threshold: float, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimit: + """Creates a new rate limit for a zone. + + Refer to the object definition for a list + of required attributes. + + Args: + zone_id: Identifier + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + match: Determines which traffic the rate limit counts towards the threshold. + + period: The time in seconds (an integer value) to count matching traffic. If the count + exceeds the configured threshold within this period, Cloudflare will perform the + configured action. + + threshold: The threshold that will trigger the configured mitigation action. Configure this + value along with the `period` property to establish a threshold per period. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._post( + f"/zones/{zone_id}/rate_limits", + body=maybe_transform( + { + "action": action, + "match": match, + "period": period, + "threshold": threshold, + }, + rate_limit_create_params.RateLimitCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimit]._unwrapper, + ), + cast_to=cast(Type[RateLimit], ResultWrapper[RateLimit]), + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + def list( + self, + *, + zone_id: str, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncV4PagePaginationArray[RateLimit]: + """ + Fetches the rate limits for a zone. + + Args: + zone_id: Identifier + + page: The page number of paginated results. + + per_page: The maximum number of results per page. You can only set the value to `1` or to + a multiple of 5 such as `5`, `10`, `15`, or `20`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/rate_limits", + page=SyncV4PagePaginationArray[RateLimit], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + rate_limit_list_params.RateLimitListParams, + ), + ), + model=RateLimit, + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + def delete( + self, + rate_limit_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimitDeleteResponse: + """ + Deletes an existing rate limit. + + Args: + zone_id: Identifier + + rate_limit_id: The unique identifier of the rate limit. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rate_limit_id: + raise ValueError(f"Expected a non-empty value for `rate_limit_id` but received {rate_limit_id!r}") + return self._delete( + f"/zones/{zone_id}/rate_limits/{rate_limit_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimitDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[RateLimitDeleteResponse], ResultWrapper[RateLimitDeleteResponse]), + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + def edit( + self, + rate_limit_id: str, + *, + zone_id: str, + action: rate_limit_edit_params.Action, + match: rate_limit_edit_params.Match, + period: float, + threshold: float, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimit: + """ + Updates an existing rate limit. + + Args: + zone_id: Identifier + + rate_limit_id: The unique identifier of the rate limit. + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + match: Determines which traffic the rate limit counts towards the threshold. + + period: The time in seconds (an integer value) to count matching traffic. If the count + exceeds the configured threshold within this period, Cloudflare will perform the + configured action. + + threshold: The threshold that will trigger the configured mitigation action. Configure this + value along with the `period` property to establish a threshold per period. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rate_limit_id: + raise ValueError(f"Expected a non-empty value for `rate_limit_id` but received {rate_limit_id!r}") + return self._put( + f"/zones/{zone_id}/rate_limits/{rate_limit_id}", + body=maybe_transform( + { + "action": action, + "match": match, + "period": period, + "threshold": threshold, + }, + rate_limit_edit_params.RateLimitEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimit]._unwrapper, + ), + cast_to=cast(Type[RateLimit], ResultWrapper[RateLimit]), + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + def get( + self, + rate_limit_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimit: + """ + Fetches the details of a rate limit. + + Args: + zone_id: Identifier + + rate_limit_id: The unique identifier of the rate limit. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rate_limit_id: + raise ValueError(f"Expected a non-empty value for `rate_limit_id` but received {rate_limit_id!r}") + return self._get( + f"/zones/{zone_id}/rate_limits/{rate_limit_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimit]._unwrapper, + ), + cast_to=cast(Type[RateLimit], ResultWrapper[RateLimit]), + ) + + +class AsyncRateLimitsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncRateLimitsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncRateLimitsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRateLimitsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncRateLimitsResourceWithStreamingResponse(self) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + async def create( + self, + *, + zone_id: str, + action: rate_limit_create_params.Action, + match: rate_limit_create_params.Match, + period: float, + threshold: float, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimit: + """Creates a new rate limit for a zone. + + Refer to the object definition for a list + of required attributes. + + Args: + zone_id: Identifier + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + match: Determines which traffic the rate limit counts towards the threshold. + + period: The time in seconds (an integer value) to count matching traffic. If the count + exceeds the configured threshold within this period, Cloudflare will perform the + configured action. + + threshold: The threshold that will trigger the configured mitigation action. Configure this + value along with the `period` property to establish a threshold per period. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._post( + f"/zones/{zone_id}/rate_limits", + body=await async_maybe_transform( + { + "action": action, + "match": match, + "period": period, + "threshold": threshold, + }, + rate_limit_create_params.RateLimitCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimit]._unwrapper, + ), + cast_to=cast(Type[RateLimit], ResultWrapper[RateLimit]), + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + def list( + self, + *, + zone_id: str, + page: float | NotGiven = NOT_GIVEN, + per_page: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[RateLimit, AsyncV4PagePaginationArray[RateLimit]]: + """ + Fetches the rate limits for a zone. + + Args: + zone_id: Identifier + + page: The page number of paginated results. + + per_page: The maximum number of results per page. You can only set the value to `1` or to + a multiple of 5 such as `5`, `10`, `15`, or `20`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get_api_list( + f"/zones/{zone_id}/rate_limits", + page=AsyncV4PagePaginationArray[RateLimit], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + rate_limit_list_params.RateLimitListParams, + ), + ), + model=RateLimit, + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + async def delete( + self, + rate_limit_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimitDeleteResponse: + """ + Deletes an existing rate limit. + + Args: + zone_id: Identifier + + rate_limit_id: The unique identifier of the rate limit. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rate_limit_id: + raise ValueError(f"Expected a non-empty value for `rate_limit_id` but received {rate_limit_id!r}") + return await self._delete( + f"/zones/{zone_id}/rate_limits/{rate_limit_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimitDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[RateLimitDeleteResponse], ResultWrapper[RateLimitDeleteResponse]), + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + async def edit( + self, + rate_limit_id: str, + *, + zone_id: str, + action: rate_limit_edit_params.Action, + match: rate_limit_edit_params.Match, + period: float, + threshold: float, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimit: + """ + Updates an existing rate limit. + + Args: + zone_id: Identifier + + rate_limit_id: The unique identifier of the rate limit. + + action: The action to perform when the threshold of matched traffic within the + configured period is exceeded. + + match: Determines which traffic the rate limit counts towards the threshold. + + period: The time in seconds (an integer value) to count matching traffic. If the count + exceeds the configured threshold within this period, Cloudflare will perform the + configured action. + + threshold: The threshold that will trigger the configured mitigation action. Configure this + value along with the `period` property to establish a threshold per period. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rate_limit_id: + raise ValueError(f"Expected a non-empty value for `rate_limit_id` but received {rate_limit_id!r}") + return await self._put( + f"/zones/{zone_id}/rate_limits/{rate_limit_id}", + body=await async_maybe_transform( + { + "action": action, + "match": match, + "period": period, + "threshold": threshold, + }, + rate_limit_edit_params.RateLimitEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimit]._unwrapper, + ), + cast_to=cast(Type[RateLimit], ResultWrapper[RateLimit]), + ) + + @typing_extensions.deprecated( + "Rate limiting API is deprecated in favour of using the Ruleset Engine. See https://developers.cloudflare.com/fundamentals/api/reference/deprecations/#rate-limiting-api-previous-version for full details." + ) + async def get( + self, + rate_limit_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> RateLimit: + """ + Fetches the details of a rate limit. + + Args: + zone_id: Identifier + + rate_limit_id: The unique identifier of the rate limit. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rate_limit_id: + raise ValueError(f"Expected a non-empty value for `rate_limit_id` but received {rate_limit_id!r}") + return await self._get( + f"/zones/{zone_id}/rate_limits/{rate_limit_id}", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RateLimit]._unwrapper, + ), + cast_to=cast(Type[RateLimit], ResultWrapper[RateLimit]), + ) + + +class RateLimitsResourceWithRawResponse: + def __init__(self, rate_limits: RateLimitsResource) -> None: + self._rate_limits = rate_limits + + self.create = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rate_limits.create # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rate_limits.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rate_limits.delete # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rate_limits.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + rate_limits.get # pyright: ignore[reportDeprecated], + ) + ) + + +class AsyncRateLimitsResourceWithRawResponse: + def __init__(self, rate_limits: AsyncRateLimitsResource) -> None: + self._rate_limits = rate_limits + + self.create = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rate_limits.create # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rate_limits.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rate_limits.delete # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rate_limits.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + rate_limits.get # pyright: ignore[reportDeprecated], + ) + ) + + +class RateLimitsResourceWithStreamingResponse: + def __init__(self, rate_limits: RateLimitsResource) -> None: + self._rate_limits = rate_limits + + self.create = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rate_limits.create # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rate_limits.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rate_limits.delete # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rate_limits.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + rate_limits.get # pyright: ignore[reportDeprecated], + ) + ) + + +class AsyncRateLimitsResourceWithStreamingResponse: + def __init__(self, rate_limits: AsyncRateLimitsResource) -> None: + self._rate_limits = rate_limits + + self.create = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rate_limits.create # pyright: ignore[reportDeprecated], + ) + ) + self.list = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rate_limits.list # pyright: ignore[reportDeprecated], + ) + ) + self.delete = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rate_limits.delete # pyright: ignore[reportDeprecated], + ) + ) + self.edit = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rate_limits.edit # pyright: ignore[reportDeprecated], + ) + ) + self.get = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + rate_limits.get # pyright: ignore[reportDeprecated], + ) + ) diff --git a/src/cloudflare/types/filters/__init__.py b/src/cloudflare/types/filters/__init__.py index f8ee8b14b1c..be5345ef460 100644 --- a/src/cloudflare/types/filters/__init__.py +++ b/src/cloudflare/types/filters/__init__.py @@ -1,3 +1,12 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations + +from .firewall_filter import FirewallFilter as FirewallFilter +from .filter_list_params import FilterListParams as FilterListParams +from .filter_create_params import FilterCreateParams as FilterCreateParams +from .filter_update_params import FilterUpdateParams as FilterUpdateParams +from .firewall_filter_param import FirewallFilterParam as FirewallFilterParam +from .filter_create_response import FilterCreateResponse as FilterCreateResponse +from .filter_bulk_delete_response import FilterBulkDeleteResponse as FilterBulkDeleteResponse +from .filter_bulk_update_response import FilterBulkUpdateResponse as FilterBulkUpdateResponse diff --git a/src/cloudflare/types/filters/filter_bulk_delete_response.py b/src/cloudflare/types/filters/filter_bulk_delete_response.py new file mode 100644 index 00000000000..7a37b1b4cbd --- /dev/null +++ b/src/cloudflare/types/filters/filter_bulk_delete_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .firewall_filter import FirewallFilter + +__all__ = ["FilterBulkDeleteResponse"] + +FilterBulkDeleteResponse: TypeAlias = List[FirewallFilter] diff --git a/src/cloudflare/types/filters/filter_bulk_update_response.py b/src/cloudflare/types/filters/filter_bulk_update_response.py new file mode 100644 index 00000000000..48059fa12a6 --- /dev/null +++ b/src/cloudflare/types/filters/filter_bulk_update_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .firewall_filter import FirewallFilter + +__all__ = ["FilterBulkUpdateResponse"] + +FilterBulkUpdateResponse: TypeAlias = List[FirewallFilter] diff --git a/src/cloudflare/types/filters/filter_create_params.py b/src/cloudflare/types/filters/filter_create_params.py new file mode 100644 index 00000000000..4c4284bb786 --- /dev/null +++ b/src/cloudflare/types/filters/filter_create_params.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["FilterCreateParams"] + + +class FilterCreateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + expression: Required[str] + """The filter expression. + + For more information, refer to + [Expressions](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/). + """ diff --git a/src/cloudflare/types/filters/filter_create_response.py b/src/cloudflare/types/filters/filter_create_response.py new file mode 100644 index 00000000000..1c979aae822 --- /dev/null +++ b/src/cloudflare/types/filters/filter_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .firewall_filter import FirewallFilter + +__all__ = ["FilterCreateResponse"] + +FilterCreateResponse: TypeAlias = List[FirewallFilter] diff --git a/src/cloudflare/types/filters/filter_list_params.py b/src/cloudflare/types/filters/filter_list_params.py new file mode 100644 index 00000000000..d90e1171696 --- /dev/null +++ b/src/cloudflare/types/filters/filter_list_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["FilterListParams"] + + +class FilterListParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + id: str + """The unique identifier of the filter.""" + + description: str + """A case-insensitive string to find in the description.""" + + expression: str + """A case-insensitive string to find in the expression.""" + + page: float + """Page number of paginated results.""" + + paused: bool + """When true, indicates that the filter is currently paused.""" + + per_page: float + """Number of filters per page.""" + + ref: str + """The filter ref (a short reference tag) to search for. Must be an exact match.""" diff --git a/src/cloudflare/types/filters/filter_update_params.py b/src/cloudflare/types/filters/filter_update_params.py new file mode 100644 index 00000000000..257141354eb --- /dev/null +++ b/src/cloudflare/types/filters/filter_update_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["FilterUpdateParams"] + + +class FilterUpdateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + body: Required[object] diff --git a/src/cloudflare/types/filters/firewall_filter.py b/src/cloudflare/types/filters/firewall_filter.py new file mode 100644 index 00000000000..03fdc13a222 --- /dev/null +++ b/src/cloudflare/types/filters/firewall_filter.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["FirewallFilter"] + + +class FirewallFilter(BaseModel): + id: Optional[str] = None + """The unique identifier of the filter.""" + + description: Optional[str] = None + """An informative summary of the filter.""" + + expression: Optional[str] = None + """The filter expression. + + For more information, refer to + [Expressions](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/). + """ + + paused: Optional[bool] = None + """When true, indicates that the filter is currently paused.""" + + ref: Optional[str] = None + """A short reference tag. Allows you to select related filters.""" diff --git a/src/cloudflare/types/filters/firewall_filter_param.py b/src/cloudflare/types/filters/firewall_filter_param.py new file mode 100644 index 00000000000..39b4c9b9620 --- /dev/null +++ b/src/cloudflare/types/filters/firewall_filter_param.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["FirewallFilterParam"] + + +class FirewallFilterParam(TypedDict, total=False): + description: str + """An informative summary of the filter.""" + + expression: str + """The filter expression. + + For more information, refer to + [Expressions](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/). + """ + + paused: bool + """When true, indicates that the filter is currently paused.""" + + ref: str + """A short reference tag. Allows you to select related filters.""" diff --git a/src/cloudflare/types/firewall/__init__.py b/src/cloudflare/types/firewall/__init__.py index 24b2000c494..0b12a89c62b 100644 --- a/src/cloudflare/types/firewall/__init__.py +++ b/src/cloudflare/types/firewall/__init__.py @@ -3,12 +3,54 @@ from __future__ import annotations from .product import Product as Product +from .lockdown import Lockdown as Lockdown from .lockdown_url import LockdownURL as LockdownURL +from .configuration import Configuration as Configuration +from .firewall_rule import FirewallRule as FirewallRule +from .deleted_filter import DeletedFilter as DeletedFilter +from .rule_get_params import RuleGetParams as RuleGetParams +from .rule_list_params import RuleListParams as RuleListParams +from .asn_configuration import ASNConfiguration as ASNConfiguration +from .ipv6_configuration import IPV6Configuration as IPV6Configuration +from .rule_create_params import RuleCreateParams as RuleCreateParams +from .rule_edit_response import RuleEditResponse as RuleEditResponse +from .rule_update_params import RuleUpdateParams as RuleUpdateParams +from .configuration_param import ConfigurationParam as ConfigurationParam +from .ua_rule_list_params import UARuleListParams as UARuleListParams +from .lockdown_list_params import LockdownListParams as LockdownListParams +from .rule_create_response import RuleCreateResponse as RuleCreateResponse +from .ua_rule_get_response import UARuleGetResponse as UARuleGetResponse +from .country_configuration import CountryConfiguration as CountryConfiguration +from .rule_bulk_edit_params import RuleBulkEditParams as RuleBulkEditParams +from .ua_rule_create_params import UARuleCreateParams as UARuleCreateParams +from .ua_rule_list_response import UARuleListResponse as UARuleListResponse +from .ua_rule_update_params import UARuleUpdateParams as UARuleUpdateParams +from .lockdown_create_params import LockdownCreateParams as LockdownCreateParams +from .lockdown_update_params import LockdownUpdateParams as LockdownUpdateParams +from .access_rule_edit_params import AccessRuleEditParams as AccessRuleEditParams from .access_rule_list_params import AccessRuleListParams as AccessRuleListParams from .asn_configuration_param import ASNConfigurationParam as ASNConfigurationParam +from .rule_bulk_edit_response import RuleBulkEditResponse as RuleBulkEditResponse +from .rule_bulk_update_params import RuleBulkUpdateParams as RuleBulkUpdateParams +from .ua_rule_create_response import UARuleCreateResponse as UARuleCreateResponse +from .ua_rule_delete_response import UARuleDeleteResponse as UARuleDeleteResponse +from .ua_rule_update_response import UARuleUpdateResponse as UARuleUpdateResponse +from .access_rule_get_response import AccessRuleGetResponse as AccessRuleGetResponse from .ipv6_configuration_param import IPV6ConfigurationParam as IPV6ConfigurationParam +from .lockdown_delete_response import LockdownDeleteResponse as LockdownDeleteResponse from .access_rule_create_params import AccessRuleCreateParams as AccessRuleCreateParams +from .access_rule_edit_response import AccessRuleEditResponse as AccessRuleEditResponse +from .access_rule_list_response import AccessRuleListResponse as AccessRuleListResponse +from .lockdown_ip_configuration import LockdownIPConfiguration as LockdownIPConfiguration +from .rule_bulk_delete_response import RuleBulkDeleteResponse as RuleBulkDeleteResponse +from .rule_bulk_update_response import RuleBulkUpdateResponse as RuleBulkUpdateResponse from .access_rule_create_response import AccessRuleCreateResponse as AccessRuleCreateResponse +from .access_rule_delete_response import AccessRuleDeleteResponse as AccessRuleDeleteResponse from .country_configuration_param import CountryConfigurationParam as CountryConfigurationParam +from .lockdown_cidr_configuration import LockdownCIDRConfiguration as LockdownCIDRConfiguration +from .access_rule_ip_configuration import AccessRuleIPConfiguration as AccessRuleIPConfiguration +from .access_rule_cidr_configuration import AccessRuleCIDRConfiguration as AccessRuleCIDRConfiguration +from .lockdown_ip_configuration_param import LockdownIPConfigurationParam as LockdownIPConfigurationParam +from .lockdown_cidr_configuration_param import LockdownCIDRConfigurationParam as LockdownCIDRConfigurationParam from .access_rule_ip_configuration_param import AccessRuleIPConfigurationParam as AccessRuleIPConfigurationParam from .access_rule_cidr_configuration_param import AccessRuleCIDRConfigurationParam as AccessRuleCIDRConfigurationParam diff --git a/src/cloudflare/types/firewall/access_rule_cidr_configuration.py b/src/cloudflare/types/firewall/access_rule_cidr_configuration.py new file mode 100644 index 00000000000..7a88829b272 --- /dev/null +++ b/src/cloudflare/types/firewall/access_rule_cidr_configuration.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["AccessRuleCIDRConfiguration"] + + +class AccessRuleCIDRConfiguration(BaseModel): + target: Optional[Literal["ip_range"]] = None + """The configuration target. + + You must set the target to `ip_range` when specifying an IP address range in the + rule. + """ + + value: Optional[str] = None + """The IP address range to match. + + You can only use prefix lengths `/16` and `/24` for IPv4 ranges, and prefix + lengths `/32`, `/48`, and `/64` for IPv6 ranges. + """ diff --git a/src/cloudflare/types/firewall/access_rule_create_response.py b/src/cloudflare/types/firewall/access_rule_create_response.py index cf90fa66c02..c7096d8a635 100644 --- a/src/cloudflare/types/firewall/access_rule_create_response.py +++ b/src/cloudflare/types/firewall/access_rule_create_response.py @@ -1,8 +1,57 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional -from typing_extensions import TypeAlias +from typing import List, Union, Optional +from datetime import datetime +from typing_extensions import Literal, TypeAlias -__all__ = ["AccessRuleCreateResponse"] +from ..._models import BaseModel +from .asn_configuration import ASNConfiguration +from .ipv6_configuration import IPV6Configuration +from .country_configuration import CountryConfiguration +from .access_rule_ip_configuration import AccessRuleIPConfiguration +from .access_rule_cidr_configuration import AccessRuleCIDRConfiguration -AccessRuleCreateResponse: TypeAlias = Union[Optional[str], Optional[object]] +__all__ = ["AccessRuleCreateResponse", "Configuration", "Scope"] + +Configuration: TypeAlias = Union[ + AccessRuleIPConfiguration, IPV6Configuration, AccessRuleCIDRConfiguration, ASNConfiguration, CountryConfiguration +] + + +class Scope(BaseModel): + id: Optional[str] = None + """Identifier""" + + email: Optional[str] = None + """The contact email address of the user.""" + + type: Optional[Literal["user", "organization"]] = None + """The scope of the rule.""" + + +class AccessRuleCreateResponse(BaseModel): + id: str + """The unique identifier of the IP Access rule.""" + + allowed_modes: List[Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"]] + """The available actions that a rule can apply to a matched request.""" + + configuration: Configuration + """The rule configuration.""" + + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"] + """The action to apply to a matched request.""" + + created_on: Optional[datetime] = None + """The timestamp of when the rule was created.""" + + modified_on: Optional[datetime] = None + """The timestamp of when the rule was last modified.""" + + notes: Optional[str] = None + """ + An informative summary of the rule, typically used as a reminder or explanation. + """ + + scope: Optional[Scope] = None + """All zones owned by the user will have the rule applied.""" diff --git a/src/cloudflare/types/firewall/access_rule_delete_response.py b/src/cloudflare/types/firewall/access_rule_delete_response.py new file mode 100644 index 00000000000..3e76fc0182b --- /dev/null +++ b/src/cloudflare/types/firewall/access_rule_delete_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + + +from ..._models import BaseModel + +__all__ = ["AccessRuleDeleteResponse"] + + +class AccessRuleDeleteResponse(BaseModel): + id: str + """Identifier""" diff --git a/src/cloudflare/types/firewall/access_rule_edit_params.py b/src/cloudflare/types/firewall/access_rule_edit_params.py new file mode 100644 index 00000000000..0b00f853493 --- /dev/null +++ b/src/cloudflare/types/firewall/access_rule_edit_params.py @@ -0,0 +1,42 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +from .asn_configuration_param import ASNConfigurationParam +from .ipv6_configuration_param import IPV6ConfigurationParam +from .country_configuration_param import CountryConfigurationParam +from .access_rule_ip_configuration_param import AccessRuleIPConfigurationParam +from .access_rule_cidr_configuration_param import AccessRuleCIDRConfigurationParam + +__all__ = ["AccessRuleEditParams", "Configuration"] + + +class AccessRuleEditParams(TypedDict, total=False): + configuration: Required[Configuration] + """The rule configuration.""" + + mode: Required[Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"]] + """The action to apply to a matched request.""" + + account_id: str + """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" + + zone_id: str + """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.""" + + notes: str + """ + An informative summary of the rule, typically used as a reminder or explanation. + """ + + +Configuration: TypeAlias = Union[ + AccessRuleIPConfigurationParam, + IPV6ConfigurationParam, + AccessRuleCIDRConfigurationParam, + ASNConfigurationParam, + CountryConfigurationParam, +] diff --git a/src/cloudflare/types/firewall/access_rule_edit_response.py b/src/cloudflare/types/firewall/access_rule_edit_response.py new file mode 100644 index 00000000000..96aef6a378f --- /dev/null +++ b/src/cloudflare/types/firewall/access_rule_edit_response.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ..._models import BaseModel +from .asn_configuration import ASNConfiguration +from .ipv6_configuration import IPV6Configuration +from .country_configuration import CountryConfiguration +from .access_rule_ip_configuration import AccessRuleIPConfiguration +from .access_rule_cidr_configuration import AccessRuleCIDRConfiguration + +__all__ = ["AccessRuleEditResponse", "Configuration", "Scope"] + +Configuration: TypeAlias = Union[ + AccessRuleIPConfiguration, IPV6Configuration, AccessRuleCIDRConfiguration, ASNConfiguration, CountryConfiguration +] + + +class Scope(BaseModel): + id: Optional[str] = None + """Identifier""" + + email: Optional[str] = None + """The contact email address of the user.""" + + type: Optional[Literal["user", "organization"]] = None + """The scope of the rule.""" + + +class AccessRuleEditResponse(BaseModel): + id: str + """The unique identifier of the IP Access rule.""" + + allowed_modes: List[Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"]] + """The available actions that a rule can apply to a matched request.""" + + configuration: Configuration + """The rule configuration.""" + + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"] + """The action to apply to a matched request.""" + + created_on: Optional[datetime] = None + """The timestamp of when the rule was created.""" + + modified_on: Optional[datetime] = None + """The timestamp of when the rule was last modified.""" + + notes: Optional[str] = None + """ + An informative summary of the rule, typically used as a reminder or explanation. + """ + + scope: Optional[Scope] = None + """All zones owned by the user will have the rule applied.""" diff --git a/src/cloudflare/types/firewall/access_rule_get_response.py b/src/cloudflare/types/firewall/access_rule_get_response.py new file mode 100644 index 00000000000..3aa8177e619 --- /dev/null +++ b/src/cloudflare/types/firewall/access_rule_get_response.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ..._models import BaseModel +from .asn_configuration import ASNConfiguration +from .ipv6_configuration import IPV6Configuration +from .country_configuration import CountryConfiguration +from .access_rule_ip_configuration import AccessRuleIPConfiguration +from .access_rule_cidr_configuration import AccessRuleCIDRConfiguration + +__all__ = ["AccessRuleGetResponse", "Configuration", "Scope"] + +Configuration: TypeAlias = Union[ + AccessRuleIPConfiguration, IPV6Configuration, AccessRuleCIDRConfiguration, ASNConfiguration, CountryConfiguration +] + + +class Scope(BaseModel): + id: Optional[str] = None + """Identifier""" + + email: Optional[str] = None + """The contact email address of the user.""" + + type: Optional[Literal["user", "organization"]] = None + """The scope of the rule.""" + + +class AccessRuleGetResponse(BaseModel): + id: str + """The unique identifier of the IP Access rule.""" + + allowed_modes: List[Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"]] + """The available actions that a rule can apply to a matched request.""" + + configuration: Configuration + """The rule configuration.""" + + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"] + """The action to apply to a matched request.""" + + created_on: Optional[datetime] = None + """The timestamp of when the rule was created.""" + + modified_on: Optional[datetime] = None + """The timestamp of when the rule was last modified.""" + + notes: Optional[str] = None + """ + An informative summary of the rule, typically used as a reminder or explanation. + """ + + scope: Optional[Scope] = None + """All zones owned by the user will have the rule applied.""" diff --git a/src/cloudflare/types/firewall/access_rule_ip_configuration.py b/src/cloudflare/types/firewall/access_rule_ip_configuration.py new file mode 100644 index 00000000000..bb5ced460e5 --- /dev/null +++ b/src/cloudflare/types/firewall/access_rule_ip_configuration.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["AccessRuleIPConfiguration"] + + +class AccessRuleIPConfiguration(BaseModel): + target: Optional[Literal["ip"]] = None + """The configuration target. + + You must set the target to `ip` when specifying an IP address in the rule. + """ + + value: Optional[str] = None + """The IP address to match. + + This address will be compared to the IP address of incoming requests. + """ diff --git a/src/cloudflare/types/firewall/access_rule_list_response.py b/src/cloudflare/types/firewall/access_rule_list_response.py new file mode 100644 index 00000000000..1f36fc9f8aa --- /dev/null +++ b/src/cloudflare/types/firewall/access_rule_list_response.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ..._models import BaseModel +from .asn_configuration import ASNConfiguration +from .ipv6_configuration import IPV6Configuration +from .country_configuration import CountryConfiguration +from .access_rule_ip_configuration import AccessRuleIPConfiguration +from .access_rule_cidr_configuration import AccessRuleCIDRConfiguration + +__all__ = ["AccessRuleListResponse", "Configuration", "Scope"] + +Configuration: TypeAlias = Union[ + AccessRuleIPConfiguration, IPV6Configuration, AccessRuleCIDRConfiguration, ASNConfiguration, CountryConfiguration +] + + +class Scope(BaseModel): + id: Optional[str] = None + """Identifier""" + + email: Optional[str] = None + """The contact email address of the user.""" + + type: Optional[Literal["user", "organization"]] = None + """The scope of the rule.""" + + +class AccessRuleListResponse(BaseModel): + id: str + """The unique identifier of the IP Access rule.""" + + allowed_modes: List[Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"]] + """The available actions that a rule can apply to a matched request.""" + + configuration: Configuration + """The rule configuration.""" + + mode: Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"] + """The action to apply to a matched request.""" + + created_on: Optional[datetime] = None + """The timestamp of when the rule was created.""" + + modified_on: Optional[datetime] = None + """The timestamp of when the rule was last modified.""" + + notes: Optional[str] = None + """ + An informative summary of the rule, typically used as a reminder or explanation. + """ + + scope: Optional[Scope] = None + """All zones owned by the user will have the rule applied.""" diff --git a/src/cloudflare/types/firewall/asn_configuration.py b/src/cloudflare/types/firewall/asn_configuration.py new file mode 100644 index 00000000000..6681a67e6b1 --- /dev/null +++ b/src/cloudflare/types/firewall/asn_configuration.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ASNConfiguration"] + + +class ASNConfiguration(BaseModel): + target: Optional[Literal["asn"]] = None + """The configuration target. + + You must set the target to `asn` when specifying an Autonomous System Number + (ASN) in the rule. + """ + + value: Optional[str] = None + """The AS number to match.""" diff --git a/src/cloudflare/types/firewall/configuration.py b/src/cloudflare/types/firewall/configuration.py new file mode 100644 index 00000000000..74e6fe404d4 --- /dev/null +++ b/src/cloudflare/types/firewall/configuration.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union +from typing_extensions import TypeAlias + +from .lockdown_ip_configuration import LockdownIPConfiguration +from .lockdown_cidr_configuration import LockdownCIDRConfiguration + +__all__ = ["Configuration", "ConfigurationItem"] + +ConfigurationItem: TypeAlias = Union[LockdownIPConfiguration, LockdownCIDRConfiguration] + +Configuration: TypeAlias = List[ConfigurationItem] diff --git a/src/cloudflare/types/firewall/configuration_param.py b/src/cloudflare/types/firewall/configuration_param.py new file mode 100644 index 00000000000..ba136e9f291 --- /dev/null +++ b/src/cloudflare/types/firewall/configuration_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Union +from typing_extensions import TypeAlias + +from .lockdown_ip_configuration_param import LockdownIPConfigurationParam +from .lockdown_cidr_configuration_param import LockdownCIDRConfigurationParam + +__all__ = ["ConfigurationParam", "ConfigurationParamItem"] + +ConfigurationParamItem: TypeAlias = Union[LockdownIPConfigurationParam, LockdownCIDRConfigurationParam] + +ConfigurationParam: TypeAlias = List[ConfigurationParamItem] diff --git a/src/cloudflare/types/firewall/country_configuration.py b/src/cloudflare/types/firewall/country_configuration.py new file mode 100644 index 00000000000..6fa7ec43fac --- /dev/null +++ b/src/cloudflare/types/firewall/country_configuration.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["CountryConfiguration"] + + +class CountryConfiguration(BaseModel): + target: Optional[Literal["country"]] = None + """The configuration target. + + You must set the target to `country` when specifying a country code in the rule. + """ + + value: Optional[str] = None + """The two-letter ISO-3166-1 alpha-2 code to match. + + For more information, refer to + [IP Access rules: Parameters](https://developers.cloudflare.com/waf/tools/ip-access-rules/parameters/#country). + """ diff --git a/src/cloudflare/types/firewall/deleted_filter.py b/src/cloudflare/types/firewall/deleted_filter.py new file mode 100644 index 00000000000..2f81710d06b --- /dev/null +++ b/src/cloudflare/types/firewall/deleted_filter.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + + +from ..._models import BaseModel + +__all__ = ["DeletedFilter"] + + +class DeletedFilter(BaseModel): + id: str + """The unique identifier of the filter.""" + + deleted: bool + """When true, indicates that the firewall rule was deleted.""" diff --git a/src/cloudflare/types/firewall/firewall_rule.py b/src/cloudflare/types/firewall/firewall_rule.py new file mode 100644 index 00000000000..1cf88c79af3 --- /dev/null +++ b/src/cloudflare/types/firewall/firewall_rule.py @@ -0,0 +1,46 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from typing_extensions import TypeAlias + +from .product import Product +from ..._models import BaseModel +from .deleted_filter import DeletedFilter +from ..rate_limits.action import Action +from ..filters.firewall_filter import FirewallFilter + +__all__ = ["FirewallRule", "Filter"] + +Filter: TypeAlias = Union[FirewallFilter, DeletedFilter] + + +class FirewallRule(BaseModel): + id: Optional[str] = None + """The unique identifier of the firewall rule.""" + + action: Optional[Action] = None + """The action to apply to a matched request. + + The `log` action is only available on an Enterprise plan. + """ + + description: Optional[str] = None + """An informative summary of the firewall rule.""" + + filter: Optional[Filter] = None + + paused: Optional[bool] = None + """When true, indicates that the firewall rule is currently paused.""" + + priority: Optional[float] = None + """The priority of the rule. + + Optional value used to define the processing order. A lower number indicates a + higher priority. If not provided, rules with a defined priority will be + processed before rules without a priority. + """ + + products: Optional[List[Product]] = None + + ref: Optional[str] = None + """A short reference tag. Allows you to select related firewall rules.""" diff --git a/src/cloudflare/types/firewall/ipv6_configuration.py b/src/cloudflare/types/firewall/ipv6_configuration.py new file mode 100644 index 00000000000..3bf40ed6bc2 --- /dev/null +++ b/src/cloudflare/types/firewall/ipv6_configuration.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["IPV6Configuration"] + + +class IPV6Configuration(BaseModel): + target: Optional[Literal["ip6"]] = None + """The configuration target. + + You must set the target to `ip6` when specifying an IPv6 address in the rule. + """ + + value: Optional[str] = None + """The IPv6 address to match.""" diff --git a/src/cloudflare/types/firewall/lockdown.py b/src/cloudflare/types/firewall/lockdown.py new file mode 100644 index 00000000000..7a1ea7038b5 --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from datetime import datetime + +from ..._models import BaseModel +from .lockdown_url import LockdownURL +from .configuration import Configuration + +__all__ = ["Lockdown"] + + +class Lockdown(BaseModel): + id: str + """The unique identifier of the Zone Lockdown rule.""" + + configurations: Configuration + """ + A list of IP addresses or CIDR ranges that will be allowed to access the URLs + specified in the Zone Lockdown rule. You can include any number of `ip` or + `ip_range` configurations. + """ + + created_on: datetime + """The timestamp of when the rule was created.""" + + description: str + """An informative summary of the rule.""" + + modified_on: datetime + """The timestamp of when the rule was last modified.""" + + paused: bool + """When true, indicates that the rule is currently paused.""" + + urls: List[LockdownURL] + """The URLs to include in the rule definition. + + You can use wildcards. Each entered URL will be escaped before use, which means + you can only use simple wildcard patterns. + """ diff --git a/src/cloudflare/types/firewall/lockdown_cidr_configuration.py b/src/cloudflare/types/firewall/lockdown_cidr_configuration.py new file mode 100644 index 00000000000..0380319616c --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_cidr_configuration.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["LockdownCIDRConfiguration"] + + +class LockdownCIDRConfiguration(BaseModel): + target: Optional[Literal["ip_range"]] = None + """The configuration target. + + You must set the target to `ip_range` when specifying an IP address range in the + Zone Lockdown rule. + """ + + value: Optional[str] = None + """The IP address range to match. You can only use prefix lengths `/16` and `/24`.""" diff --git a/src/cloudflare/types/firewall/lockdown_cidr_configuration_param.py b/src/cloudflare/types/firewall/lockdown_cidr_configuration_param.py new file mode 100644 index 00000000000..2748218d297 --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_cidr_configuration_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["LockdownCIDRConfigurationParam"] + + +class LockdownCIDRConfigurationParam(TypedDict, total=False): + target: Literal["ip_range"] + """The configuration target. + + You must set the target to `ip_range` when specifying an IP address range in the + Zone Lockdown rule. + """ + + value: str + """The IP address range to match. You can only use prefix lengths `/16` and `/24`.""" diff --git a/src/cloudflare/types/firewall/lockdown_create_params.py b/src/cloudflare/types/firewall/lockdown_create_params.py new file mode 100644 index 00000000000..6b9c5e01839 --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_create_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List +from typing_extensions import Required, TypedDict + +from .waf.override_url import OverrideURL +from .configuration_param import ConfigurationParam + +__all__ = ["LockdownCreateParams"] + + +class LockdownCreateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + configurations: Required[ConfigurationParam] + """ + A list of IP addresses or CIDR ranges that will be allowed to access the URLs + specified in the Zone Lockdown rule. You can include any number of `ip` or + `ip_range` configurations. + """ + + urls: Required[List[OverrideURL]] + """The URLs to include in the current WAF override. + + You can use wildcards. Each entered URL will be escaped before use, which means + you can only use simple wildcard patterns. + """ diff --git a/src/cloudflare/types/firewall/lockdown_delete_response.py b/src/cloudflare/types/firewall/lockdown_delete_response.py new file mode 100644 index 00000000000..6938edb1610 --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_delete_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["LockdownDeleteResponse"] + + +class LockdownDeleteResponse(BaseModel): + id: Optional[str] = None + """The unique identifier of the Zone Lockdown rule.""" diff --git a/src/cloudflare/types/firewall/lockdown_ip_configuration.py b/src/cloudflare/types/firewall/lockdown_ip_configuration.py new file mode 100644 index 00000000000..5961692c88f --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_ip_configuration.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["LockdownIPConfiguration"] + + +class LockdownIPConfiguration(BaseModel): + target: Optional[Literal["ip"]] = None + """The configuration target. + + You must set the target to `ip` when specifying an IP address in the Zone + Lockdown rule. + """ + + value: Optional[str] = None + """The IP address to match. + + This address will be compared to the IP address of incoming requests. + """ diff --git a/src/cloudflare/types/firewall/lockdown_ip_configuration_param.py b/src/cloudflare/types/firewall/lockdown_ip_configuration_param.py new file mode 100644 index 00000000000..8c3b3322596 --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_ip_configuration_param.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["LockdownIPConfigurationParam"] + + +class LockdownIPConfigurationParam(TypedDict, total=False): + target: Literal["ip"] + """The configuration target. + + You must set the target to `ip` when specifying an IP address in the Zone + Lockdown rule. + """ + + value: str + """The IP address to match. + + This address will be compared to the IP address of incoming requests. + """ diff --git a/src/cloudflare/types/firewall/lockdown_list_params.py b/src/cloudflare/types/firewall/lockdown_list_params.py new file mode 100644 index 00000000000..81df31e16fe --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_list_params.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["LockdownListParams"] + + +class LockdownListParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + created_on: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """The timestamp of when the rule was created.""" + + description: str + """A string to search for in the description of existing rules.""" + + description_search: str + """A string to search for in the description of existing rules.""" + + ip: str + """A single IP address to search for in existing rules.""" + + ip_range_search: str + """A single IP address range to search for in existing rules.""" + + ip_search: str + """A single IP address to search for in existing rules.""" + + modified_on: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """The timestamp of when the rule was last modified.""" + + page: float + """Page number of paginated results.""" + + per_page: float + """The maximum number of results per page. + + You can only set the value to `1` or to a multiple of 5 such as `5`, `10`, `15`, + or `20`. + """ + + priority: float + """The priority of the rule to control the processing order. + + A lower number indicates higher priority. If not provided, any rules with a + configured priority will be processed before rules without a priority. + """ + + uri_search: str + """A single URI to search for in the list of URLs of existing rules.""" diff --git a/src/cloudflare/types/firewall/lockdown_update_params.py b/src/cloudflare/types/firewall/lockdown_update_params.py new file mode 100644 index 00000000000..c194e1e4904 --- /dev/null +++ b/src/cloudflare/types/firewall/lockdown_update_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List +from typing_extensions import Required, TypedDict + +from .waf.override_url import OverrideURL +from .configuration_param import ConfigurationParam + +__all__ = ["LockdownUpdateParams"] + + +class LockdownUpdateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + configurations: Required[ConfigurationParam] + """ + A list of IP addresses or CIDR ranges that will be allowed to access the URLs + specified in the Zone Lockdown rule. You can include any number of `ip` or + `ip_range` configurations. + """ + + urls: Required[List[OverrideURL]] + """The URLs to include in the current WAF override. + + You can use wildcards. Each entered URL will be escaped before use, which means + you can only use simple wildcard patterns. + """ diff --git a/src/cloudflare/types/firewall/rule_bulk_delete_response.py b/src/cloudflare/types/firewall/rule_bulk_delete_response.py new file mode 100644 index 00000000000..535192b8afb --- /dev/null +++ b/src/cloudflare/types/firewall/rule_bulk_delete_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .firewall_rule import FirewallRule + +__all__ = ["RuleBulkDeleteResponse"] + +RuleBulkDeleteResponse: TypeAlias = List[FirewallRule] diff --git a/src/cloudflare/types/firewall/rule_bulk_edit_params.py b/src/cloudflare/types/firewall/rule_bulk_edit_params.py new file mode 100644 index 00000000000..f47f108569c --- /dev/null +++ b/src/cloudflare/types/firewall/rule_bulk_edit_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RuleBulkEditParams"] + + +class RuleBulkEditParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + body: Required[object] diff --git a/src/cloudflare/types/firewall/rule_bulk_edit_response.py b/src/cloudflare/types/firewall/rule_bulk_edit_response.py new file mode 100644 index 00000000000..f6d4fdaf7f2 --- /dev/null +++ b/src/cloudflare/types/firewall/rule_bulk_edit_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .firewall_rule import FirewallRule + +__all__ = ["RuleBulkEditResponse"] + +RuleBulkEditResponse: TypeAlias = List[FirewallRule] diff --git a/src/cloudflare/types/firewall/rule_bulk_update_params.py b/src/cloudflare/types/firewall/rule_bulk_update_params.py new file mode 100644 index 00000000000..97016b19207 --- /dev/null +++ b/src/cloudflare/types/firewall/rule_bulk_update_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RuleBulkUpdateParams"] + + +class RuleBulkUpdateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + body: Required[object] diff --git a/src/cloudflare/types/firewall/rule_bulk_update_response.py b/src/cloudflare/types/firewall/rule_bulk_update_response.py new file mode 100644 index 00000000000..d8bacf8ab0e --- /dev/null +++ b/src/cloudflare/types/firewall/rule_bulk_update_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .firewall_rule import FirewallRule + +__all__ = ["RuleBulkUpdateResponse"] + +RuleBulkUpdateResponse: TypeAlias = List[FirewallRule] diff --git a/src/cloudflare/types/firewall/rule_create_params.py b/src/cloudflare/types/firewall/rule_create_params.py new file mode 100644 index 00000000000..32aa378e63e --- /dev/null +++ b/src/cloudflare/types/firewall/rule_create_params.py @@ -0,0 +1,59 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from ..filters.firewall_filter_param import FirewallFilterParam + +__all__ = ["RuleCreateParams", "Action", "ActionResponse"] + + +class RuleCreateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + action: Required[Action] + """ + The action to perform when the threshold of matched traffic within the + configured period is exceeded. + """ + + filter: Required[FirewallFilterParam] + + +class ActionResponse(TypedDict, total=False): + body: str + """The response body to return. + + The value must conform to the configured content type. + """ + + content_type: str + """The content type of the body. + + Must be one of the following: `text/plain`, `text/xml`, or `application/json`. + """ + + +class Action(TypedDict, total=False): + mode: Literal["simulate", "ban", "challenge", "js_challenge", "managed_challenge"] + """The action to perform.""" + + response: ActionResponse + """A custom content type and reponse to return when the threshold is exceeded. + + The custom response configured in this object will override the custom error for + the zone. This object is optional. Notes: If you omit this object, Cloudflare + will use the default HTML error page. If "mode" is "challenge", + "managed_challenge", or "js_challenge", Cloudflare will use the zone challenge + pages and you should not provide the "response" object. + """ + + timeout: float + """The time in seconds during which Cloudflare will perform the mitigation action. + + Must be an integer value greater than or equal to the period. Notes: If "mode" + is "challenge", "managed_challenge", or "js_challenge", Cloudflare will use the + zone's Challenge Passage time and you should not provide this value. + """ diff --git a/src/cloudflare/types/firewall/rule_create_response.py b/src/cloudflare/types/firewall/rule_create_response.py new file mode 100644 index 00000000000..78ca0455e97 --- /dev/null +++ b/src/cloudflare/types/firewall/rule_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .firewall_rule import FirewallRule + +__all__ = ["RuleCreateResponse"] + +RuleCreateResponse: TypeAlias = List[FirewallRule] diff --git a/src/cloudflare/types/pagerules/setting_list_response.py b/src/cloudflare/types/firewall/rule_edit_response.py similarity index 55% rename from src/cloudflare/types/pagerules/setting_list_response.py rename to src/cloudflare/types/firewall/rule_edit_response.py index 69e8c454a09..078cb92e0e8 100644 --- a/src/cloudflare/types/pagerules/setting_list_response.py +++ b/src/cloudflare/types/firewall/rule_edit_response.py @@ -3,6 +3,8 @@ from typing import List from typing_extensions import TypeAlias -__all__ = ["SettingListResponse"] +from .firewall_rule import FirewallRule -SettingListResponse: TypeAlias = List[object] +__all__ = ["RuleEditResponse"] + +RuleEditResponse: TypeAlias = List[FirewallRule] diff --git a/src/cloudflare/types/firewall/rule_get_params.py b/src/cloudflare/types/firewall/rule_get_params.py new file mode 100644 index 00000000000..6dff4946cc7 --- /dev/null +++ b/src/cloudflare/types/firewall/rule_get_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RuleGetParams"] + + +class RuleGetParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + id: str + """The unique identifier of the firewall rule.""" diff --git a/src/cloudflare/types/firewall/rule_list_params.py b/src/cloudflare/types/firewall/rule_list_params.py new file mode 100644 index 00000000000..b01c0dd4fc7 --- /dev/null +++ b/src/cloudflare/types/firewall/rule_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RuleListParams"] + + +class RuleListParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + id: str + """The unique identifier of the firewall rule.""" + + action: str + """The action to search for. Must be an exact match.""" + + description: str + """A case-insensitive string to find in the description.""" + + page: float + """Page number of paginated results.""" + + paused: bool + """When true, indicates that the firewall rule is currently paused.""" + + per_page: float + """Number of firewall rules per page.""" diff --git a/src/cloudflare/types/firewall/rule_update_params.py b/src/cloudflare/types/firewall/rule_update_params.py new file mode 100644 index 00000000000..0e9c27e89b5 --- /dev/null +++ b/src/cloudflare/types/firewall/rule_update_params.py @@ -0,0 +1,59 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from ..filters.firewall_filter_param import FirewallFilterParam + +__all__ = ["RuleUpdateParams", "Action", "ActionResponse"] + + +class RuleUpdateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + action: Required[Action] + """ + The action to perform when the threshold of matched traffic within the + configured period is exceeded. + """ + + filter: Required[FirewallFilterParam] + + +class ActionResponse(TypedDict, total=False): + body: str + """The response body to return. + + The value must conform to the configured content type. + """ + + content_type: str + """The content type of the body. + + Must be one of the following: `text/plain`, `text/xml`, or `application/json`. + """ + + +class Action(TypedDict, total=False): + mode: Literal["simulate", "ban", "challenge", "js_challenge", "managed_challenge"] + """The action to perform.""" + + response: ActionResponse + """A custom content type and reponse to return when the threshold is exceeded. + + The custom response configured in this object will override the custom error for + the zone. This object is optional. Notes: If you omit this object, Cloudflare + will use the default HTML error page. If "mode" is "challenge", + "managed_challenge", or "js_challenge", Cloudflare will use the zone challenge + pages and you should not provide the "response" object. + """ + + timeout: float + """The time in seconds during which Cloudflare will perform the mitigation action. + + Must be an integer value greater than or equal to the period. Notes: If "mode" + is "challenge", "managed_challenge", or "js_challenge", Cloudflare will use the + zone's Challenge Passage time and you should not provide this value. + """ diff --git a/src/cloudflare/types/firewall/ua_rule_create_params.py b/src/cloudflare/types/firewall/ua_rule_create_params.py new file mode 100644 index 00000000000..7c56210bb79 --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_create_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +from .asn_configuration_param import ASNConfigurationParam +from .ipv6_configuration_param import IPV6ConfigurationParam +from .country_configuration_param import CountryConfigurationParam +from .access_rule_ip_configuration_param import AccessRuleIPConfigurationParam +from .access_rule_cidr_configuration_param import AccessRuleCIDRConfigurationParam + +__all__ = ["UARuleCreateParams", "Configuration"] + + +class UARuleCreateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + configuration: Required[Configuration] + """The rule configuration.""" + + mode: Required[Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"]] + """The action to apply to a matched request.""" + + +Configuration: TypeAlias = Union[ + AccessRuleIPConfigurationParam, + IPV6ConfigurationParam, + AccessRuleCIDRConfigurationParam, + ASNConfigurationParam, + CountryConfigurationParam, +] diff --git a/src/cloudflare/types/firewall/ua_rule_create_response.py b/src/cloudflare/types/firewall/ua_rule_create_response.py new file mode 100644 index 00000000000..bb2d6671967 --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_create_response.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union, Optional +from typing_extensions import TypeAlias + +__all__ = ["UARuleCreateResponse"] + +UARuleCreateResponse: TypeAlias = Union[Optional[str], Optional[object]] diff --git a/src/cloudflare/types/firewall/ua_rule_delete_response.py b/src/cloudflare/types/firewall/ua_rule_delete_response.py new file mode 100644 index 00000000000..0d7cbd7d69d --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_delete_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["UARuleDeleteResponse"] + + +class UARuleDeleteResponse(BaseModel): + id: Optional[str] = None + """The unique identifier of the User Agent Blocking rule.""" diff --git a/src/cloudflare/types/firewall/ua_rule_get_response.py b/src/cloudflare/types/firewall/ua_rule_get_response.py new file mode 100644 index 00000000000..10613bd3d5b --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_get_response.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union, Optional +from typing_extensions import TypeAlias + +__all__ = ["UARuleGetResponse"] + +UARuleGetResponse: TypeAlias = Union[Optional[str], Optional[object]] diff --git a/src/cloudflare/types/firewall/ua_rule_list_params.py b/src/cloudflare/types/firewall/ua_rule_list_params.py new file mode 100644 index 00000000000..5eb6fe0245a --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_list_params.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["UARuleListParams"] + + +class UARuleListParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + description: str + """A string to search for in the description of existing rules.""" + + description_search: str + """A string to search for in the description of existing rules.""" + + page: float + """Page number of paginated results.""" + + per_page: float + """The maximum number of results per page. + + You can only set the value to `1` or to a multiple of 5 such as `5`, `10`, `15`, + or `20`. + """ + + ua_search: str + """A string to search for in the user agent values of existing rules.""" diff --git a/src/cloudflare/types/firewall/ua_rule_list_response.py b/src/cloudflare/types/firewall/ua_rule_list_response.py new file mode 100644 index 00000000000..d3426a93fc3 --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_list_response.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["UARuleListResponse", "Configuration"] + + +class Configuration(BaseModel): + target: Optional[str] = None + """The configuration target for this rule. + + You must set the target to `ua` for User Agent Blocking rules. + """ + + value: Optional[str] = None + """The exact user agent string to match. + + This value will be compared to the received `User-Agent` HTTP header value. + """ + + +class UARuleListResponse(BaseModel): + id: Optional[str] = None + """The unique identifier of the User Agent Blocking rule.""" + + configuration: Optional[Configuration] = None + """The configuration object for the current rule.""" + + description: Optional[str] = None + """An informative summary of the rule.""" + + mode: Optional[Literal["block", "challenge", "js_challenge", "managed_challenge"]] = None + """The action to apply to a matched request.""" + + paused: Optional[bool] = None + """When true, indicates that the rule is currently paused.""" diff --git a/src/cloudflare/types/firewall/ua_rule_update_params.py b/src/cloudflare/types/firewall/ua_rule_update_params.py new file mode 100644 index 00000000000..5e7eae10702 --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_update_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +from .asn_configuration_param import ASNConfigurationParam +from .ipv6_configuration_param import IPV6ConfigurationParam +from .country_configuration_param import CountryConfigurationParam +from .access_rule_ip_configuration_param import AccessRuleIPConfigurationParam +from .access_rule_cidr_configuration_param import AccessRuleCIDRConfigurationParam + +__all__ = ["UARuleUpdateParams", "Configuration"] + + +class UARuleUpdateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + configuration: Required[Configuration] + """The rule configuration.""" + + mode: Required[Literal["block", "challenge", "whitelist", "js_challenge", "managed_challenge"]] + """The action to apply to a matched request.""" + + +Configuration: TypeAlias = Union[ + AccessRuleIPConfigurationParam, + IPV6ConfigurationParam, + AccessRuleCIDRConfigurationParam, + ASNConfigurationParam, + CountryConfigurationParam, +] diff --git a/src/cloudflare/types/firewall/ua_rule_update_response.py b/src/cloudflare/types/firewall/ua_rule_update_response.py new file mode 100644 index 00000000000..4dc4d0ae168 --- /dev/null +++ b/src/cloudflare/types/firewall/ua_rule_update_response.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union, Optional +from typing_extensions import TypeAlias + +__all__ = ["UARuleUpdateResponse"] + +UARuleUpdateResponse: TypeAlias = Union[Optional[str], Optional[object]] diff --git a/src/cloudflare/types/firewall/waf/__init__.py b/src/cloudflare/types/firewall/waf/__init__.py index 94d4bfb4479..45373da4f22 100644 --- a/src/cloudflare/types/firewall/waf/__init__.py +++ b/src/cloudflare/types/firewall/waf/__init__.py @@ -2,4 +2,15 @@ from __future__ import annotations +from .override import Override as Override +from .waf_rule import WAFRule as WAFRule from .override_url import OverrideURL as OverrideURL +from .rewrite_action import RewriteAction as RewriteAction +from .waf_rule_param import WAFRuleParam as WAFRuleParam +from .package_list_params import PackageListParams as PackageListParams +from .override_list_params import OverrideListParams as OverrideListParams +from .package_get_response import PackageGetResponse as PackageGetResponse +from .rewrite_action_param import RewriteActionParam as RewriteActionParam +from .override_create_params import OverrideCreateParams as OverrideCreateParams +from .override_update_params import OverrideUpdateParams as OverrideUpdateParams +from .override_delete_response import OverrideDeleteResponse as OverrideDeleteResponse diff --git a/src/cloudflare/types/firewall/waf/override.py b/src/cloudflare/types/firewall/waf/override.py new file mode 100644 index 00000000000..a758b89d18b --- /dev/null +++ b/src/cloudflare/types/firewall/waf/override.py @@ -0,0 +1,59 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional + +from .waf_rule import WAFRule +from ...._models import BaseModel +from .override_url import OverrideURL +from .rewrite_action import RewriteAction + +__all__ = ["Override"] + + +class Override(BaseModel): + id: Optional[str] = None + """The unique identifier of the WAF override.""" + + description: Optional[str] = None + """An informative summary of the current URI-based WAF override.""" + + groups: Optional[Dict[str, object]] = None + """ + An object that allows you to enable or disable WAF rule groups for the current + WAF override. Each key of this object must be the ID of a WAF rule group, and + each value must be a valid WAF action (usually `default` or `disable`). When + creating a new URI-based WAF override, you must provide a `groups` object or a + `rules` object. + """ + + paused: Optional[bool] = None + """When true, indicates that the WAF package is currently paused.""" + + priority: Optional[float] = None + """ + The relative priority of the current URI-based WAF override when multiple + overrides match a single URL. A lower number indicates higher priority. Higher + priority overrides may overwrite values set by lower priority overrides. + """ + + rewrite_action: Optional[RewriteAction] = None + """ + Specifies that, when a WAF rule matches, its configured action will be replaced + by the action configured in this object. + """ + + rules: Optional[WAFRule] = None + """An object that allows you to override the action of specific WAF rules. + + Each key of this object must be the ID of a WAF rule, and each value must be a + valid WAF action. Unless you are disabling a rule, ensure that you also enable + the rule group that this WAF rule belongs to. When creating a new URI-based WAF + override, you must provide a `groups` object or a `rules` object. + """ + + urls: Optional[List[OverrideURL]] = None + """The URLs to include in the current WAF override. + + You can use wildcards. Each entered URL will be escaped before use, which means + you can only use simple wildcard patterns. + """ diff --git a/src/cloudflare/types/firewall/waf/override_create_params.py b/src/cloudflare/types/firewall/waf/override_create_params.py new file mode 100644 index 00000000000..759ff41f3b9 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/override_create_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List +from typing_extensions import Required, TypedDict + +from .override_url import OverrideURL + +__all__ = ["OverrideCreateParams"] + + +class OverrideCreateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + urls: Required[List[OverrideURL]] + """The URLs to include in the current WAF override. + + You can use wildcards. Each entered URL will be escaped before use, which means + you can only use simple wildcard patterns. + """ diff --git a/src/cloudflare/types/firewall/waf/override_delete_response.py b/src/cloudflare/types/firewall/waf/override_delete_response.py new file mode 100644 index 00000000000..2c2830fff95 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/override_delete_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ...._models import BaseModel + +__all__ = ["OverrideDeleteResponse"] + + +class OverrideDeleteResponse(BaseModel): + id: Optional[str] = None + """The unique identifier of the WAF override.""" diff --git a/src/cloudflare/types/firewall/waf/override_list_params.py b/src/cloudflare/types/firewall/waf/override_list_params.py new file mode 100644 index 00000000000..59c53ef8846 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/override_list_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["OverrideListParams"] + + +class OverrideListParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + page: float + """The page number of paginated results.""" + + per_page: float + """The number of WAF overrides per page.""" diff --git a/src/cloudflare/types/firewall/waf/override_update_params.py b/src/cloudflare/types/firewall/waf/override_update_params.py new file mode 100644 index 00000000000..8375c6fcdfd --- /dev/null +++ b/src/cloudflare/types/firewall/waf/override_update_params.py @@ -0,0 +1,42 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List +from typing_extensions import Required, TypedDict + +from .override_url import OverrideURL +from .waf_rule_param import WAFRuleParam +from .rewrite_action_param import RewriteActionParam + +__all__ = ["OverrideUpdateParams"] + + +class OverrideUpdateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + id: Required[str] + """Identifier""" + + rewrite_action: Required[RewriteActionParam] + """ + Specifies that, when a WAF rule matches, its configured action will be replaced + by the action configured in this object. + """ + + rules: Required[WAFRuleParam] + """An object that allows you to override the action of specific WAF rules. + + Each key of this object must be the ID of a WAF rule, and each value must be a + valid WAF action. Unless you are disabling a rule, ensure that you also enable + the rule group that this WAF rule belongs to. When creating a new URI-based WAF + override, you must provide a `groups` object or a `rules` object. + """ + + urls: Required[List[OverrideURL]] + """The URLs to include in the current WAF override. + + You can use wildcards. Each entered URL will be escaped before use, which means + you can only use simple wildcard patterns. + """ diff --git a/src/cloudflare/types/firewall/waf/package_get_response.py b/src/cloudflare/types/firewall/waf/package_get_response.py new file mode 100644 index 00000000000..6c5fda24087 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/package_get_response.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias + +from ...._models import BaseModel +from ...shared.response_info import ResponseInfo + +__all__ = ["PackageGetResponse", "FirewallAPIResponseSingle", "Result"] + + +class FirewallAPIResponseSingle(BaseModel): + errors: List[ResponseInfo] + + messages: List[ResponseInfo] + + result: Union[Optional[str], Optional[object]] + + success: Literal[True] + """Whether the API call was successful""" + + +class Result(BaseModel): + result: Optional[object] = None + + +PackageGetResponse: TypeAlias = Union[FirewallAPIResponseSingle, Result] diff --git a/src/cloudflare/types/firewall/waf/package_list_params.py b/src/cloudflare/types/firewall/waf/package_list_params.py new file mode 100644 index 00000000000..7c4cfda6bfe --- /dev/null +++ b/src/cloudflare/types/firewall/waf/package_list_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["PackageListParams"] + + +class PackageListParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + direction: Literal["asc", "desc"] + """The direction used to sort returned packages.""" + + match: Literal["any", "all"] + """When set to `all`, all the search requirements must match. + + When set to `any`, only one of the search requirements has to match. + """ + + name: str + """The name of the WAF package.""" + + order: Literal["name"] + """The field used to sort returned packages.""" + + page: float + """The page number of paginated results.""" + + per_page: float + """The number of packages per page.""" diff --git a/src/cloudflare/types/firewall/waf/rewrite_action.py b/src/cloudflare/types/firewall/waf/rewrite_action.py new file mode 100644 index 00000000000..cfdd8b826c1 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/rewrite_action.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["RewriteAction"] + + +class RewriteAction(BaseModel): + block: Optional[Literal["challenge", "block", "simulate", "disable", "default"]] = None + """The WAF rule action to apply.""" + + challenge: Optional[Literal["challenge", "block", "simulate", "disable", "default"]] = None + """The WAF rule action to apply.""" + + default: Optional[Literal["challenge", "block", "simulate", "disable", "default"]] = None + """The WAF rule action to apply.""" + + disable: Optional[Literal["challenge", "block", "simulate", "disable", "default"]] = None + """The WAF rule action to apply.""" + + simulate: Optional[Literal["challenge", "block", "simulate", "disable", "default"]] = None + """The WAF rule action to apply.""" diff --git a/src/cloudflare/types/firewall/waf/rewrite_action_param.py b/src/cloudflare/types/firewall/waf/rewrite_action_param.py new file mode 100644 index 00000000000..9115252b294 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/rewrite_action_param.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["RewriteActionParam"] + + +class RewriteActionParam(TypedDict, total=False): + block: Literal["challenge", "block", "simulate", "disable", "default"] + """The WAF rule action to apply.""" + + challenge: Literal["challenge", "block", "simulate", "disable", "default"] + """The WAF rule action to apply.""" + + default: Literal["challenge", "block", "simulate", "disable", "default"] + """The WAF rule action to apply.""" + + disable: Literal["challenge", "block", "simulate", "disable", "default"] + """The WAF rule action to apply.""" + + simulate: Literal["challenge", "block", "simulate", "disable", "default"] + """The WAF rule action to apply.""" diff --git a/src/cloudflare/types/firewall/waf/waf_rule.py b/src/cloudflare/types/firewall/waf/waf_rule.py new file mode 100644 index 00000000000..3e6abc12da2 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/waf_rule.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict +from typing_extensions import Literal, TypeAlias + +__all__ = ["WAFRule"] + +WAFRule: TypeAlias = Dict[str, Literal["challenge", "block", "simulate", "disable", "default"]] diff --git a/src/cloudflare/types/firewall/waf/waf_rule_param.py b/src/cloudflare/types/firewall/waf/waf_rule_param.py new file mode 100644 index 00000000000..80123839548 --- /dev/null +++ b/src/cloudflare/types/firewall/waf/waf_rule_param.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Literal, TypeAlias + +__all__ = ["WAFRuleParam"] + +WAFRuleParam: TypeAlias = Dict[str, Literal["challenge", "block", "simulate", "disable", "default"]] diff --git a/src/cloudflare/types/pagerules/__init__.py b/src/cloudflare/types/pagerules/__init__.py index 067b2828771..a023afa9b37 100644 --- a/src/cloudflare/types/pagerules/__init__.py +++ b/src/cloudflare/types/pagerules/__init__.py @@ -7,7 +7,6 @@ from .target_param import TargetParam as TargetParam from .pagerule_edit_params import PageruleEditParams as PageruleEditParams from .pagerule_list_params import PageruleListParams as PageruleListParams -from .setting_list_response import SettingListResponse as SettingListResponse from .pagerule_create_params import PageruleCreateParams as PageruleCreateParams from .pagerule_list_response import PageruleListResponse as PageruleListResponse from .pagerule_update_params import PageruleUpdateParams as PageruleUpdateParams diff --git a/src/cloudflare/types/pagerules/page_rule.py b/src/cloudflare/types/pagerules/page_rule.py index 198378298e6..a8d30133f49 100644 --- a/src/cloudflare/types/pagerules/page_rule.py +++ b/src/cloudflare/types/pagerules/page_rule.py @@ -1,16 +1,261 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, Annotated, TypeAlias from .target import Target +from ..._utils import PropertyInfo from ..._models import BaseModel +from ..zones.ssl import SSL +from ..zones.waf import WAF +from ..zones.mirage import Mirage +from ..zones.polish import Polish +from ..zones.cache_level import CacheLevel +from ..zones.browser_check import BrowserCheck +from ..zones.rocket_loader import RocketLoader +from ..zones.ip_geolocation import IPGeolocation +from ..zones.security_level import SecurityLevel +from ..zones.always_use_https import AlwaysUseHTTPS +from ..zones.development_mode import DevelopmentMode +from ..zones.browser_cache_ttl import BrowserCacheTTL +from ..zones.email_obfuscation import EmailObfuscation +from ..zones.hotlink_protection import HotlinkProtection +from ..zones.response_buffering import ResponseBuffering +from ..zones.server_side_excludes import ServerSideExcludes +from ..zones.true_client_ip_header import TrueClientIPHeader +from ..zones.automatic_https_rewrites import AutomaticHTTPSRewrites +from ..zones.opportunistic_encryption import OpportunisticEncryption +from ..zones.origin_error_page_pass_thru import OriginErrorPagePassThru +from ..zones.sort_query_string_for_cache import SortQueryStringForCache -__all__ = ["PageRule", "Action", "ActionValue"] +__all__ = [ + "PageRule", + "Action", + "ActionBypassCacheOnCookie", + "ActionCacheByDeviceType", + "ActionCacheDeceptionArmor", + "ActionCacheKey", + "ActionCacheKeyValue", + "ActionCacheKeyValueCookie", + "ActionCacheKeyValueHeader", + "ActionCacheKeyValueHost", + "ActionCacheKeyValueQueryString", + "ActionCacheKeyValueUser", + "ActionCacheKeyFields", + "ActionCacheOnCookie", + "ActionCacheTTLByStatus", + "ActionDDoSProtection", + "ActionDisableApps", + "ActionDisablePerformance", + "ActionDisableSecurity", + "ActionDisableZaraz", + "ActionEdgeCacheTTL", + "ActionExplicitCacheControl", + "ActionForwardingURL", + "ActionForwardingURLValue", + "ActionHostHeaderOverride", + "ActionMinify", + "ActionPurgeByPageRule", + "ActionResolveOverride", + "ActionResolveOverrideValue", + "ActionRespectStrongEtag", +] -class ActionValue(BaseModel): +class ActionBypassCacheOnCookie(BaseModel): + id: Optional[Literal["bypass_cache_on_cookie"]] = None + """ + Bypass cache and fetch resources from the origin server if a regular expression + matches against a cookie name present in the request. + """ + + value: Optional[str] = None + """The regular expression to use for matching cookie names in the request. + + Refer to + [Bypass Cache on Cookie setting](https://developers.cloudflare.com/rules/page-rules/reference/additional-reference/#bypass-cache-on-cookie-setting) + to learn about limited regular expression support. + """ + + +class ActionCacheByDeviceType(BaseModel): + id: Optional[Literal["cache_by_device_type"]] = None + """Separate cached content based on the visitor's device type.""" + + value: Optional[Literal["on", "off"]] = None + """The status of Cache By Device Type.""" + + +class ActionCacheDeceptionArmor(BaseModel): + id: Optional[Literal["cache_deception_armor"]] = None + """ + Protect from web cache deception attacks while still allowing static assets to + be cached. This setting verifies that the URL's extension matches the returned + `Content-Type`. + """ + + value: Optional[Literal["on", "off"]] = None + """The status of Cache Deception Armor.""" + + +class ActionCacheKeyValueCookie(BaseModel): + check_presence: Optional[List[str]] = None + """ + A list of cookies to check for the presence of, without including their actual + values. + """ + + include: Optional[List[str]] = None + """A list of cookies to include.""" + + +class ActionCacheKeyValueHeader(BaseModel): + check_presence: Optional[List[str]] = None + """ + A list of headers to check for the presence of, without including their actual + values. + """ + + exclude: Optional[List[str]] = None + """A list of headers to ignore.""" + + include: Optional[List[str]] = None + """A list of headers to include.""" + + +class ActionCacheKeyValueHost(BaseModel): + resolved: Optional[bool] = None + """Whether to include the Host header in the HTTP request sent to the origin.""" + + +class ActionCacheKeyValueQueryString(BaseModel): + exclude: Union[Literal["*"], List[str], None] = None + """Ignore all query string parameters.""" + + include: Union[Literal["*"], List[str], None] = None + """Include all query string parameters.""" + + +class ActionCacheKeyValueUser(BaseModel): + device_type: Optional[bool] = None + """ + Classifies a request as `mobile`, `desktop`, or `tablet` based on the User + Agent. + """ + + geo: Optional[bool] = None + """Includes the client's country, derived from the IP address.""" + + lang: Optional[bool] = None + """ + Includes the first language code contained in the `Accept-Language` header sent + by the client. + """ + + +class ActionCacheKeyValue(BaseModel): + cookie: Optional[ActionCacheKeyValueCookie] = None + """Controls which cookies appear in the Cache Key.""" + + header: Optional[ActionCacheKeyValueHeader] = None + """Controls which headers go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + host: Optional[ActionCacheKeyValueHost] = None + """Determines which host header to include in the Cache Key.""" + + query_string: Optional[ActionCacheKeyValueQueryString] = None + """Controls which URL query string parameters go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + user: Optional[ActionCacheKeyValueUser] = None + """Feature fields to add features about the end-user (client) into the Cache Key.""" + + +class ActionCacheKey(BaseModel): + id: Optional[Literal["cache_key"]] = None + """ + Control specifically what variables to include when deciding which resources to + cache. This allows customers to determine what to cache based on something other + than just the URL. + """ + + value: Optional[ActionCacheKeyValue] = None + + +class ActionCacheKeyFields(BaseModel): + id: Optional[Literal["cache_key_fields"]] = None + + +class ActionCacheOnCookie(BaseModel): + id: Optional[Literal["cache_on_cookie"]] = None + + +class ActionCacheTTLByStatus(BaseModel): + id: Optional[Literal["cache_ttl_by_status"]] = None + + +class ActionDDoSProtection(BaseModel): + id: Optional[Literal["ddos_protection"]] = None + + +class ActionDisableApps(BaseModel): + id: Optional[Literal["disable_apps"]] = None + """ + Turn off all active + [Cloudflare Apps](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-apps/) + (deprecated). + """ + + +class ActionDisablePerformance(BaseModel): + id: Optional[Literal["disable_performance"]] = None + """ + Turn off + [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/), + [Mirage](https://developers.cloudflare.com/speed/optimization/images/mirage/), + and [Polish](https://developers.cloudflare.com/images/polish/). + """ + + +class ActionDisableSecurity(BaseModel): + id: Optional[Literal["disable_security"]] = None + """ + Turn off + [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/), + [Rate Limiting (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-rate-limiting/), + [Scrape Shield](https://developers.cloudflare.com/waf/tools/scrape-shield/), + [URL (Zone) Lockdown](https://developers.cloudflare.com/waf/tools/zone-lockdown/), + and + [WAF managed rules (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/). + """ + + +class ActionDisableZaraz(BaseModel): + id: Optional[Literal["disable_zaraz"]] = None + """Turn off [Zaraz](https://developers.cloudflare.com/zaraz/).""" + + +class ActionEdgeCacheTTL(BaseModel): + id: Optional[Literal["edge_cache_ttl"]] = None + """Specify how long to cache a resource in the Cloudflare global network. + + _Edge Cache TTL_ is not visible in response headers. + """ + + value: Optional[int] = None + + +class ActionExplicitCacheControl(BaseModel): + id: Optional[Literal["explicit_cache_control"]] = None + + +class ActionForwardingURLValue(BaseModel): status_code: Optional[Literal[301, 302]] = None """The status code to use for the URL redirect. @@ -24,7 +269,7 @@ class ActionValue(BaseModel): """ -class Action(BaseModel): +class ActionForwardingURL(BaseModel): id: Optional[Literal["forwarding_url"]] = None """Redirects one URL to another using an `HTTP 301/302` redirect. @@ -32,7 +277,94 @@ class Action(BaseModel): [Wildcard matching and referencing](https://developers.cloudflare.com/rules/page-rules/reference/wildcard-matching/). """ - value: Optional[ActionValue] = None + value: Optional[ActionForwardingURLValue] = None + + +class ActionHostHeaderOverride(BaseModel): + id: Optional[Literal["host_header_override"]] = None + """Apply a specific host header.""" + + value: Optional[str] = None + """The hostname to use in the `Host` header""" + + +class ActionMinify(BaseModel): + id: Optional[Literal["minify"]] = None + + +class ActionPurgeByPageRule(BaseModel): + id: Optional[Literal["purge_by_page_rule"]] = None + + +class ActionResolveOverrideValue(BaseModel): + value: Optional[str] = None + """The origin address you want to override with.""" + + +class ActionResolveOverride(BaseModel): + id: Optional[Literal["resolve_override"]] = None + """Change the origin address to the value specified in this setting.""" + + value: Optional[ActionResolveOverrideValue] = None + + +class ActionRespectStrongEtag(BaseModel): + id: Optional[Literal["respect_strong_etag"]] = None + """ + Turn on or off byte-for-byte equivalency checks between the Cloudflare cache and + the origin server. + """ + + value: Optional[Literal["on", "off"]] = None + """The status of Respect Strong ETags""" + + +Action: TypeAlias = Annotated[ + Union[ + AlwaysUseHTTPS, + AutomaticHTTPSRewrites, + BrowserCacheTTL, + BrowserCheck, + ActionBypassCacheOnCookie, + ActionCacheByDeviceType, + ActionCacheDeceptionArmor, + ActionCacheKey, + ActionCacheKeyFields, + CacheLevel, + ActionCacheOnCookie, + ActionCacheTTLByStatus, + ActionDDoSProtection, + DevelopmentMode, + ActionDisableApps, + ActionDisablePerformance, + ActionDisableSecurity, + ActionDisableZaraz, + ActionEdgeCacheTTL, + EmailObfuscation, + ActionExplicitCacheControl, + ActionForwardingURL, + ActionHostHeaderOverride, + HotlinkProtection, + IPGeolocation, + ActionMinify, + Mirage, + OpportunisticEncryption, + OriginErrorPagePassThru, + Polish, + ActionPurgeByPageRule, + ActionResolveOverride, + ActionRespectStrongEtag, + ResponseBuffering, + RocketLoader, + SecurityLevel, + ServerSideExcludes, + SortQueryStringForCache, + SSL, + TrueClientIPHeader, + WAF, + ], + PropertyInfo(discriminator="id"), +] class PageRule(BaseModel): diff --git a/src/cloudflare/types/pagerules/pagerule_create_params.py b/src/cloudflare/types/pagerules/pagerule_create_params.py index 1a554231d3a..805b38d7e00 100644 --- a/src/cloudflare/types/pagerules/pagerule_create_params.py +++ b/src/cloudflare/types/pagerules/pagerule_create_params.py @@ -2,12 +2,64 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Literal, Required, TypedDict +from typing import List, Union, Iterable +from typing_extensions import Literal, Required, TypeAlias, TypedDict from .target_param import TargetParam +from ..zones.ssl_param import SSLParam +from ..zones.waf_param import WAFParam +from ..zones.mirage_param import MirageParam +from ..zones.polish_param import PolishParam +from ..zones.cache_level_param import CacheLevelParam +from ..zones.browser_check_param import BrowserCheckParam +from ..zones.rocket_loader_param import RocketLoaderParam +from ..zones.ip_geolocation_param import IPGeolocationParam +from ..zones.security_level_param import SecurityLevelParam +from ..zones.always_use_https_param import AlwaysUseHTTPSParam +from ..zones.development_mode_param import DevelopmentModeParam +from ..zones.browser_cache_ttl_param import BrowserCacheTTLParam +from ..zones.email_obfuscation_param import EmailObfuscationParam +from ..zones.hotlink_protection_param import HotlinkProtectionParam +from ..zones.response_buffering_param import ResponseBufferingParam +from ..zones.server_side_excludes_param import ServerSideExcludesParam +from ..zones.true_client_ip_header_param import TrueClientIPHeaderParam +from ..zones.automatic_https_rewrites_param import AutomaticHTTPSRewritesParam +from ..zones.opportunistic_encryption_param import OpportunisticEncryptionParam +from ..zones.origin_error_page_pass_thru_param import OriginErrorPagePassThruParam +from ..zones.sort_query_string_for_cache_param import SortQueryStringForCacheParam -__all__ = ["PageruleCreateParams", "Action", "ActionValue"] +__all__ = [ + "PageruleCreateParams", + "Action", + "ActionBypassCacheOnCookie", + "ActionCacheByDeviceType", + "ActionCacheDeceptionArmor", + "ActionCacheKey", + "ActionCacheKeyValue", + "ActionCacheKeyValueCookie", + "ActionCacheKeyValueHeader", + "ActionCacheKeyValueHost", + "ActionCacheKeyValueQueryString", + "ActionCacheKeyValueUser", + "ActionCacheKeyFields", + "ActionCacheOnCookie", + "ActionCacheTTLByStatus", + "ActionDDoSProtection", + "ActionDisableApps", + "ActionDisablePerformance", + "ActionDisableSecurity", + "ActionDisableZaraz", + "ActionEdgeCacheTTL", + "ActionExplicitCacheControl", + "ActionForwardingURL", + "ActionForwardingURLValue", + "ActionHostHeaderOverride", + "ActionMinify", + "ActionPurgeByPageRule", + "ActionResolveOverride", + "ActionResolveOverrideValue", + "ActionRespectStrongEtag", +] class PageruleCreateParams(TypedDict, total=False): @@ -36,7 +88,199 @@ class PageruleCreateParams(TypedDict, total=False): """The status of the Page Rule.""" -class ActionValue(TypedDict, total=False): +class ActionBypassCacheOnCookie(TypedDict, total=False): + id: Literal["bypass_cache_on_cookie"] + """ + Bypass cache and fetch resources from the origin server if a regular expression + matches against a cookie name present in the request. + """ + + value: str + """The regular expression to use for matching cookie names in the request. + + Refer to + [Bypass Cache on Cookie setting](https://developers.cloudflare.com/rules/page-rules/reference/additional-reference/#bypass-cache-on-cookie-setting) + to learn about limited regular expression support. + """ + + +class ActionCacheByDeviceType(TypedDict, total=False): + id: Literal["cache_by_device_type"] + """Separate cached content based on the visitor's device type.""" + + value: Literal["on", "off"] + """The status of Cache By Device Type.""" + + +class ActionCacheDeceptionArmor(TypedDict, total=False): + id: Literal["cache_deception_armor"] + """ + Protect from web cache deception attacks while still allowing static assets to + be cached. This setting verifies that the URL's extension matches the returned + `Content-Type`. + """ + + value: Literal["on", "off"] + """The status of Cache Deception Armor.""" + + +class ActionCacheKeyValueCookie(TypedDict, total=False): + check_presence: List[str] + """ + A list of cookies to check for the presence of, without including their actual + values. + """ + + include: List[str] + """A list of cookies to include.""" + + +class ActionCacheKeyValueHeader(TypedDict, total=False): + check_presence: List[str] + """ + A list of headers to check for the presence of, without including their actual + values. + """ + + exclude: List[str] + """A list of headers to ignore.""" + + include: List[str] + """A list of headers to include.""" + + +class ActionCacheKeyValueHost(TypedDict, total=False): + resolved: bool + """Whether to include the Host header in the HTTP request sent to the origin.""" + + +class ActionCacheKeyValueQueryString(TypedDict, total=False): + exclude: Union[Literal["*"], List[str]] + """Ignore all query string parameters.""" + + include: Union[Literal["*"], List[str]] + """Include all query string parameters.""" + + +class ActionCacheKeyValueUser(TypedDict, total=False): + device_type: bool + """ + Classifies a request as `mobile`, `desktop`, or `tablet` based on the User + Agent. + """ + + geo: bool + """Includes the client's country, derived from the IP address.""" + + lang: bool + """ + Includes the first language code contained in the `Accept-Language` header sent + by the client. + """ + + +class ActionCacheKeyValue(TypedDict, total=False): + cookie: ActionCacheKeyValueCookie + """Controls which cookies appear in the Cache Key.""" + + header: ActionCacheKeyValueHeader + """Controls which headers go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + host: ActionCacheKeyValueHost + """Determines which host header to include in the Cache Key.""" + + query_string: ActionCacheKeyValueQueryString + """Controls which URL query string parameters go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + user: ActionCacheKeyValueUser + """Feature fields to add features about the end-user (client) into the Cache Key.""" + + +class ActionCacheKey(TypedDict, total=False): + id: Literal["cache_key"] + """ + Control specifically what variables to include when deciding which resources to + cache. This allows customers to determine what to cache based on something other + than just the URL. + """ + + value: ActionCacheKeyValue + + +class ActionCacheKeyFields(TypedDict, total=False): + id: Literal["cache_key_fields"] + + +class ActionCacheOnCookie(TypedDict, total=False): + id: Literal["cache_on_cookie"] + + +class ActionCacheTTLByStatus(TypedDict, total=False): + id: Literal["cache_ttl_by_status"] + + +class ActionDDoSProtection(TypedDict, total=False): + id: Literal["ddos_protection"] + + +class ActionDisableApps(TypedDict, total=False): + id: Literal["disable_apps"] + """ + Turn off all active + [Cloudflare Apps](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-apps/) + (deprecated). + """ + + +class ActionDisablePerformance(TypedDict, total=False): + id: Literal["disable_performance"] + """ + Turn off + [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/), + [Mirage](https://developers.cloudflare.com/speed/optimization/images/mirage/), + and [Polish](https://developers.cloudflare.com/images/polish/). + """ + + +class ActionDisableSecurity(TypedDict, total=False): + id: Literal["disable_security"] + """ + Turn off + [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/), + [Rate Limiting (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-rate-limiting/), + [Scrape Shield](https://developers.cloudflare.com/waf/tools/scrape-shield/), + [URL (Zone) Lockdown](https://developers.cloudflare.com/waf/tools/zone-lockdown/), + and + [WAF managed rules (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/). + """ + + +class ActionDisableZaraz(TypedDict, total=False): + id: Literal["disable_zaraz"] + """Turn off [Zaraz](https://developers.cloudflare.com/zaraz/).""" + + +class ActionEdgeCacheTTL(TypedDict, total=False): + id: Literal["edge_cache_ttl"] + """Specify how long to cache a resource in the Cloudflare global network. + + _Edge Cache TTL_ is not visible in response headers. + """ + + value: int + + +class ActionExplicitCacheControl(TypedDict, total=False): + id: Literal["explicit_cache_control"] + + +class ActionForwardingURLValue(TypedDict, total=False): status_code: Literal[301, 302] """The status code to use for the URL redirect. @@ -50,7 +294,7 @@ class ActionValue(TypedDict, total=False): """ -class Action(TypedDict, total=False): +class ActionForwardingURL(TypedDict, total=False): id: Literal["forwarding_url"] """Redirects one URL to another using an `HTTP 301/302` redirect. @@ -58,4 +302,88 @@ class Action(TypedDict, total=False): [Wildcard matching and referencing](https://developers.cloudflare.com/rules/page-rules/reference/wildcard-matching/). """ - value: ActionValue + value: ActionForwardingURLValue + + +class ActionHostHeaderOverride(TypedDict, total=False): + id: Literal["host_header_override"] + """Apply a specific host header.""" + + value: str + """The hostname to use in the `Host` header""" + + +class ActionMinify(TypedDict, total=False): + id: Literal["minify"] + + +class ActionPurgeByPageRule(TypedDict, total=False): + id: Literal["purge_by_page_rule"] + + +class ActionResolveOverrideValue(TypedDict, total=False): + value: str + """The origin address you want to override with.""" + + +class ActionResolveOverride(TypedDict, total=False): + id: Literal["resolve_override"] + """Change the origin address to the value specified in this setting.""" + + value: ActionResolveOverrideValue + + +class ActionRespectStrongEtag(TypedDict, total=False): + id: Literal["respect_strong_etag"] + """ + Turn on or off byte-for-byte equivalency checks between the Cloudflare cache and + the origin server. + """ + + value: Literal["on", "off"] + """The status of Respect Strong ETags""" + + +Action: TypeAlias = Union[ + AlwaysUseHTTPSParam, + AutomaticHTTPSRewritesParam, + BrowserCacheTTLParam, + BrowserCheckParam, + ActionBypassCacheOnCookie, + ActionCacheByDeviceType, + ActionCacheDeceptionArmor, + ActionCacheKey, + ActionCacheKeyFields, + CacheLevelParam, + ActionCacheOnCookie, + ActionCacheTTLByStatus, + ActionDDoSProtection, + DevelopmentModeParam, + ActionDisableApps, + ActionDisablePerformance, + ActionDisableSecurity, + ActionDisableZaraz, + ActionEdgeCacheTTL, + EmailObfuscationParam, + ActionExplicitCacheControl, + ActionForwardingURL, + ActionHostHeaderOverride, + HotlinkProtectionParam, + IPGeolocationParam, + ActionMinify, + MirageParam, + OpportunisticEncryptionParam, + OriginErrorPagePassThruParam, + PolishParam, + ActionPurgeByPageRule, + ActionResolveOverride, + ActionRespectStrongEtag, + ResponseBufferingParam, + RocketLoaderParam, + SecurityLevelParam, + ServerSideExcludesParam, + SortQueryStringForCacheParam, + SSLParam, + TrueClientIPHeaderParam, + WAFParam, +] diff --git a/src/cloudflare/types/pagerules/pagerule_edit_params.py b/src/cloudflare/types/pagerules/pagerule_edit_params.py index e785a2c36c0..e7efd955291 100644 --- a/src/cloudflare/types/pagerules/pagerule_edit_params.py +++ b/src/cloudflare/types/pagerules/pagerule_edit_params.py @@ -2,12 +2,64 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Literal, Required, TypedDict +from typing import List, Union, Iterable +from typing_extensions import Literal, Required, TypeAlias, TypedDict from .target_param import TargetParam +from ..zones.ssl_param import SSLParam +from ..zones.waf_param import WAFParam +from ..zones.mirage_param import MirageParam +from ..zones.polish_param import PolishParam +from ..zones.cache_level_param import CacheLevelParam +from ..zones.browser_check_param import BrowserCheckParam +from ..zones.rocket_loader_param import RocketLoaderParam +from ..zones.ip_geolocation_param import IPGeolocationParam +from ..zones.security_level_param import SecurityLevelParam +from ..zones.always_use_https_param import AlwaysUseHTTPSParam +from ..zones.development_mode_param import DevelopmentModeParam +from ..zones.browser_cache_ttl_param import BrowserCacheTTLParam +from ..zones.email_obfuscation_param import EmailObfuscationParam +from ..zones.hotlink_protection_param import HotlinkProtectionParam +from ..zones.response_buffering_param import ResponseBufferingParam +from ..zones.server_side_excludes_param import ServerSideExcludesParam +from ..zones.true_client_ip_header_param import TrueClientIPHeaderParam +from ..zones.automatic_https_rewrites_param import AutomaticHTTPSRewritesParam +from ..zones.opportunistic_encryption_param import OpportunisticEncryptionParam +from ..zones.origin_error_page_pass_thru_param import OriginErrorPagePassThruParam +from ..zones.sort_query_string_for_cache_param import SortQueryStringForCacheParam -__all__ = ["PageruleEditParams", "Action", "ActionValue"] +__all__ = [ + "PageruleEditParams", + "Action", + "ActionBypassCacheOnCookie", + "ActionCacheByDeviceType", + "ActionCacheDeceptionArmor", + "ActionCacheKey", + "ActionCacheKeyValue", + "ActionCacheKeyValueCookie", + "ActionCacheKeyValueHeader", + "ActionCacheKeyValueHost", + "ActionCacheKeyValueQueryString", + "ActionCacheKeyValueUser", + "ActionCacheKeyFields", + "ActionCacheOnCookie", + "ActionCacheTTLByStatus", + "ActionDDoSProtection", + "ActionDisableApps", + "ActionDisablePerformance", + "ActionDisableSecurity", + "ActionDisableZaraz", + "ActionEdgeCacheTTL", + "ActionExplicitCacheControl", + "ActionForwardingURL", + "ActionForwardingURLValue", + "ActionHostHeaderOverride", + "ActionMinify", + "ActionPurgeByPageRule", + "ActionResolveOverride", + "ActionResolveOverrideValue", + "ActionRespectStrongEtag", +] class PageruleEditParams(TypedDict, total=False): @@ -36,7 +88,199 @@ class PageruleEditParams(TypedDict, total=False): """The rule targets to evaluate on each request.""" -class ActionValue(TypedDict, total=False): +class ActionBypassCacheOnCookie(TypedDict, total=False): + id: Literal["bypass_cache_on_cookie"] + """ + Bypass cache and fetch resources from the origin server if a regular expression + matches against a cookie name present in the request. + """ + + value: str + """The regular expression to use for matching cookie names in the request. + + Refer to + [Bypass Cache on Cookie setting](https://developers.cloudflare.com/rules/page-rules/reference/additional-reference/#bypass-cache-on-cookie-setting) + to learn about limited regular expression support. + """ + + +class ActionCacheByDeviceType(TypedDict, total=False): + id: Literal["cache_by_device_type"] + """Separate cached content based on the visitor's device type.""" + + value: Literal["on", "off"] + """The status of Cache By Device Type.""" + + +class ActionCacheDeceptionArmor(TypedDict, total=False): + id: Literal["cache_deception_armor"] + """ + Protect from web cache deception attacks while still allowing static assets to + be cached. This setting verifies that the URL's extension matches the returned + `Content-Type`. + """ + + value: Literal["on", "off"] + """The status of Cache Deception Armor.""" + + +class ActionCacheKeyValueCookie(TypedDict, total=False): + check_presence: List[str] + """ + A list of cookies to check for the presence of, without including their actual + values. + """ + + include: List[str] + """A list of cookies to include.""" + + +class ActionCacheKeyValueHeader(TypedDict, total=False): + check_presence: List[str] + """ + A list of headers to check for the presence of, without including their actual + values. + """ + + exclude: List[str] + """A list of headers to ignore.""" + + include: List[str] + """A list of headers to include.""" + + +class ActionCacheKeyValueHost(TypedDict, total=False): + resolved: bool + """Whether to include the Host header in the HTTP request sent to the origin.""" + + +class ActionCacheKeyValueQueryString(TypedDict, total=False): + exclude: Union[Literal["*"], List[str]] + """Ignore all query string parameters.""" + + include: Union[Literal["*"], List[str]] + """Include all query string parameters.""" + + +class ActionCacheKeyValueUser(TypedDict, total=False): + device_type: bool + """ + Classifies a request as `mobile`, `desktop`, or `tablet` based on the User + Agent. + """ + + geo: bool + """Includes the client's country, derived from the IP address.""" + + lang: bool + """ + Includes the first language code contained in the `Accept-Language` header sent + by the client. + """ + + +class ActionCacheKeyValue(TypedDict, total=False): + cookie: ActionCacheKeyValueCookie + """Controls which cookies appear in the Cache Key.""" + + header: ActionCacheKeyValueHeader + """Controls which headers go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + host: ActionCacheKeyValueHost + """Determines which host header to include in the Cache Key.""" + + query_string: ActionCacheKeyValueQueryString + """Controls which URL query string parameters go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + user: ActionCacheKeyValueUser + """Feature fields to add features about the end-user (client) into the Cache Key.""" + + +class ActionCacheKey(TypedDict, total=False): + id: Literal["cache_key"] + """ + Control specifically what variables to include when deciding which resources to + cache. This allows customers to determine what to cache based on something other + than just the URL. + """ + + value: ActionCacheKeyValue + + +class ActionCacheKeyFields(TypedDict, total=False): + id: Literal["cache_key_fields"] + + +class ActionCacheOnCookie(TypedDict, total=False): + id: Literal["cache_on_cookie"] + + +class ActionCacheTTLByStatus(TypedDict, total=False): + id: Literal["cache_ttl_by_status"] + + +class ActionDDoSProtection(TypedDict, total=False): + id: Literal["ddos_protection"] + + +class ActionDisableApps(TypedDict, total=False): + id: Literal["disable_apps"] + """ + Turn off all active + [Cloudflare Apps](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-apps/) + (deprecated). + """ + + +class ActionDisablePerformance(TypedDict, total=False): + id: Literal["disable_performance"] + """ + Turn off + [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/), + [Mirage](https://developers.cloudflare.com/speed/optimization/images/mirage/), + and [Polish](https://developers.cloudflare.com/images/polish/). + """ + + +class ActionDisableSecurity(TypedDict, total=False): + id: Literal["disable_security"] + """ + Turn off + [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/), + [Rate Limiting (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-rate-limiting/), + [Scrape Shield](https://developers.cloudflare.com/waf/tools/scrape-shield/), + [URL (Zone) Lockdown](https://developers.cloudflare.com/waf/tools/zone-lockdown/), + and + [WAF managed rules (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/). + """ + + +class ActionDisableZaraz(TypedDict, total=False): + id: Literal["disable_zaraz"] + """Turn off [Zaraz](https://developers.cloudflare.com/zaraz/).""" + + +class ActionEdgeCacheTTL(TypedDict, total=False): + id: Literal["edge_cache_ttl"] + """Specify how long to cache a resource in the Cloudflare global network. + + _Edge Cache TTL_ is not visible in response headers. + """ + + value: int + + +class ActionExplicitCacheControl(TypedDict, total=False): + id: Literal["explicit_cache_control"] + + +class ActionForwardingURLValue(TypedDict, total=False): status_code: Literal[301, 302] """The status code to use for the URL redirect. @@ -50,7 +294,7 @@ class ActionValue(TypedDict, total=False): """ -class Action(TypedDict, total=False): +class ActionForwardingURL(TypedDict, total=False): id: Literal["forwarding_url"] """Redirects one URL to another using an `HTTP 301/302` redirect. @@ -58,4 +302,88 @@ class Action(TypedDict, total=False): [Wildcard matching and referencing](https://developers.cloudflare.com/rules/page-rules/reference/wildcard-matching/). """ - value: ActionValue + value: ActionForwardingURLValue + + +class ActionHostHeaderOverride(TypedDict, total=False): + id: Literal["host_header_override"] + """Apply a specific host header.""" + + value: str + """The hostname to use in the `Host` header""" + + +class ActionMinify(TypedDict, total=False): + id: Literal["minify"] + + +class ActionPurgeByPageRule(TypedDict, total=False): + id: Literal["purge_by_page_rule"] + + +class ActionResolveOverrideValue(TypedDict, total=False): + value: str + """The origin address you want to override with.""" + + +class ActionResolveOverride(TypedDict, total=False): + id: Literal["resolve_override"] + """Change the origin address to the value specified in this setting.""" + + value: ActionResolveOverrideValue + + +class ActionRespectStrongEtag(TypedDict, total=False): + id: Literal["respect_strong_etag"] + """ + Turn on or off byte-for-byte equivalency checks between the Cloudflare cache and + the origin server. + """ + + value: Literal["on", "off"] + """The status of Respect Strong ETags""" + + +Action: TypeAlias = Union[ + AlwaysUseHTTPSParam, + AutomaticHTTPSRewritesParam, + BrowserCacheTTLParam, + BrowserCheckParam, + ActionBypassCacheOnCookie, + ActionCacheByDeviceType, + ActionCacheDeceptionArmor, + ActionCacheKey, + ActionCacheKeyFields, + CacheLevelParam, + ActionCacheOnCookie, + ActionCacheTTLByStatus, + ActionDDoSProtection, + DevelopmentModeParam, + ActionDisableApps, + ActionDisablePerformance, + ActionDisableSecurity, + ActionDisableZaraz, + ActionEdgeCacheTTL, + EmailObfuscationParam, + ActionExplicitCacheControl, + ActionForwardingURL, + ActionHostHeaderOverride, + HotlinkProtectionParam, + IPGeolocationParam, + ActionMinify, + MirageParam, + OpportunisticEncryptionParam, + OriginErrorPagePassThruParam, + PolishParam, + ActionPurgeByPageRule, + ActionResolveOverride, + ActionRespectStrongEtag, + ResponseBufferingParam, + RocketLoaderParam, + SecurityLevelParam, + ServerSideExcludesParam, + SortQueryStringForCacheParam, + SSLParam, + TrueClientIPHeaderParam, + WAFParam, +] diff --git a/src/cloudflare/types/pagerules/pagerule_update_params.py b/src/cloudflare/types/pagerules/pagerule_update_params.py index 88e80a5b5a7..5177c102917 100644 --- a/src/cloudflare/types/pagerules/pagerule_update_params.py +++ b/src/cloudflare/types/pagerules/pagerule_update_params.py @@ -2,12 +2,64 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Literal, Required, TypedDict +from typing import List, Union, Iterable +from typing_extensions import Literal, Required, TypeAlias, TypedDict from .target_param import TargetParam +from ..zones.ssl_param import SSLParam +from ..zones.waf_param import WAFParam +from ..zones.mirage_param import MirageParam +from ..zones.polish_param import PolishParam +from ..zones.cache_level_param import CacheLevelParam +from ..zones.browser_check_param import BrowserCheckParam +from ..zones.rocket_loader_param import RocketLoaderParam +from ..zones.ip_geolocation_param import IPGeolocationParam +from ..zones.security_level_param import SecurityLevelParam +from ..zones.always_use_https_param import AlwaysUseHTTPSParam +from ..zones.development_mode_param import DevelopmentModeParam +from ..zones.browser_cache_ttl_param import BrowserCacheTTLParam +from ..zones.email_obfuscation_param import EmailObfuscationParam +from ..zones.hotlink_protection_param import HotlinkProtectionParam +from ..zones.response_buffering_param import ResponseBufferingParam +from ..zones.server_side_excludes_param import ServerSideExcludesParam +from ..zones.true_client_ip_header_param import TrueClientIPHeaderParam +from ..zones.automatic_https_rewrites_param import AutomaticHTTPSRewritesParam +from ..zones.opportunistic_encryption_param import OpportunisticEncryptionParam +from ..zones.origin_error_page_pass_thru_param import OriginErrorPagePassThruParam +from ..zones.sort_query_string_for_cache_param import SortQueryStringForCacheParam -__all__ = ["PageruleUpdateParams", "Action", "ActionValue"] +__all__ = [ + "PageruleUpdateParams", + "Action", + "ActionBypassCacheOnCookie", + "ActionCacheByDeviceType", + "ActionCacheDeceptionArmor", + "ActionCacheKey", + "ActionCacheKeyValue", + "ActionCacheKeyValueCookie", + "ActionCacheKeyValueHeader", + "ActionCacheKeyValueHost", + "ActionCacheKeyValueQueryString", + "ActionCacheKeyValueUser", + "ActionCacheKeyFields", + "ActionCacheOnCookie", + "ActionCacheTTLByStatus", + "ActionDDoSProtection", + "ActionDisableApps", + "ActionDisablePerformance", + "ActionDisableSecurity", + "ActionDisableZaraz", + "ActionEdgeCacheTTL", + "ActionExplicitCacheControl", + "ActionForwardingURL", + "ActionForwardingURLValue", + "ActionHostHeaderOverride", + "ActionMinify", + "ActionPurgeByPageRule", + "ActionResolveOverride", + "ActionResolveOverrideValue", + "ActionRespectStrongEtag", +] class PageruleUpdateParams(TypedDict, total=False): @@ -36,7 +88,199 @@ class PageruleUpdateParams(TypedDict, total=False): """The status of the Page Rule.""" -class ActionValue(TypedDict, total=False): +class ActionBypassCacheOnCookie(TypedDict, total=False): + id: Literal["bypass_cache_on_cookie"] + """ + Bypass cache and fetch resources from the origin server if a regular expression + matches against a cookie name present in the request. + """ + + value: str + """The regular expression to use for matching cookie names in the request. + + Refer to + [Bypass Cache on Cookie setting](https://developers.cloudflare.com/rules/page-rules/reference/additional-reference/#bypass-cache-on-cookie-setting) + to learn about limited regular expression support. + """ + + +class ActionCacheByDeviceType(TypedDict, total=False): + id: Literal["cache_by_device_type"] + """Separate cached content based on the visitor's device type.""" + + value: Literal["on", "off"] + """The status of Cache By Device Type.""" + + +class ActionCacheDeceptionArmor(TypedDict, total=False): + id: Literal["cache_deception_armor"] + """ + Protect from web cache deception attacks while still allowing static assets to + be cached. This setting verifies that the URL's extension matches the returned + `Content-Type`. + """ + + value: Literal["on", "off"] + """The status of Cache Deception Armor.""" + + +class ActionCacheKeyValueCookie(TypedDict, total=False): + check_presence: List[str] + """ + A list of cookies to check for the presence of, without including their actual + values. + """ + + include: List[str] + """A list of cookies to include.""" + + +class ActionCacheKeyValueHeader(TypedDict, total=False): + check_presence: List[str] + """ + A list of headers to check for the presence of, without including their actual + values. + """ + + exclude: List[str] + """A list of headers to ignore.""" + + include: List[str] + """A list of headers to include.""" + + +class ActionCacheKeyValueHost(TypedDict, total=False): + resolved: bool + """Whether to include the Host header in the HTTP request sent to the origin.""" + + +class ActionCacheKeyValueQueryString(TypedDict, total=False): + exclude: Union[Literal["*"], List[str]] + """Ignore all query string parameters.""" + + include: Union[Literal["*"], List[str]] + """Include all query string parameters.""" + + +class ActionCacheKeyValueUser(TypedDict, total=False): + device_type: bool + """ + Classifies a request as `mobile`, `desktop`, or `tablet` based on the User + Agent. + """ + + geo: bool + """Includes the client's country, derived from the IP address.""" + + lang: bool + """ + Includes the first language code contained in the `Accept-Language` header sent + by the client. + """ + + +class ActionCacheKeyValue(TypedDict, total=False): + cookie: ActionCacheKeyValueCookie + """Controls which cookies appear in the Cache Key.""" + + header: ActionCacheKeyValueHeader + """Controls which headers go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + host: ActionCacheKeyValueHost + """Determines which host header to include in the Cache Key.""" + + query_string: ActionCacheKeyValueQueryString + """Controls which URL query string parameters go into the Cache Key. + + Exactly one of `include` or `exclude` is expected. + """ + + user: ActionCacheKeyValueUser + """Feature fields to add features about the end-user (client) into the Cache Key.""" + + +class ActionCacheKey(TypedDict, total=False): + id: Literal["cache_key"] + """ + Control specifically what variables to include when deciding which resources to + cache. This allows customers to determine what to cache based on something other + than just the URL. + """ + + value: ActionCacheKeyValue + + +class ActionCacheKeyFields(TypedDict, total=False): + id: Literal["cache_key_fields"] + + +class ActionCacheOnCookie(TypedDict, total=False): + id: Literal["cache_on_cookie"] + + +class ActionCacheTTLByStatus(TypedDict, total=False): + id: Literal["cache_ttl_by_status"] + + +class ActionDDoSProtection(TypedDict, total=False): + id: Literal["ddos_protection"] + + +class ActionDisableApps(TypedDict, total=False): + id: Literal["disable_apps"] + """ + Turn off all active + [Cloudflare Apps](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-apps/) + (deprecated). + """ + + +class ActionDisablePerformance(TypedDict, total=False): + id: Literal["disable_performance"] + """ + Turn off + [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/), + [Mirage](https://developers.cloudflare.com/speed/optimization/images/mirage/), + and [Polish](https://developers.cloudflare.com/images/polish/). + """ + + +class ActionDisableSecurity(TypedDict, total=False): + id: Literal["disable_security"] + """ + Turn off + [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/), + [Rate Limiting (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-rate-limiting/), + [Scrape Shield](https://developers.cloudflare.com/waf/tools/scrape-shield/), + [URL (Zone) Lockdown](https://developers.cloudflare.com/waf/tools/zone-lockdown/), + and + [WAF managed rules (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/). + """ + + +class ActionDisableZaraz(TypedDict, total=False): + id: Literal["disable_zaraz"] + """Turn off [Zaraz](https://developers.cloudflare.com/zaraz/).""" + + +class ActionEdgeCacheTTL(TypedDict, total=False): + id: Literal["edge_cache_ttl"] + """Specify how long to cache a resource in the Cloudflare global network. + + _Edge Cache TTL_ is not visible in response headers. + """ + + value: int + + +class ActionExplicitCacheControl(TypedDict, total=False): + id: Literal["explicit_cache_control"] + + +class ActionForwardingURLValue(TypedDict, total=False): status_code: Literal[301, 302] """The status code to use for the URL redirect. @@ -50,7 +294,7 @@ class ActionValue(TypedDict, total=False): """ -class Action(TypedDict, total=False): +class ActionForwardingURL(TypedDict, total=False): id: Literal["forwarding_url"] """Redirects one URL to another using an `HTTP 301/302` redirect. @@ -58,4 +302,88 @@ class Action(TypedDict, total=False): [Wildcard matching and referencing](https://developers.cloudflare.com/rules/page-rules/reference/wildcard-matching/). """ - value: ActionValue + value: ActionForwardingURLValue + + +class ActionHostHeaderOverride(TypedDict, total=False): + id: Literal["host_header_override"] + """Apply a specific host header.""" + + value: str + """The hostname to use in the `Host` header""" + + +class ActionMinify(TypedDict, total=False): + id: Literal["minify"] + + +class ActionPurgeByPageRule(TypedDict, total=False): + id: Literal["purge_by_page_rule"] + + +class ActionResolveOverrideValue(TypedDict, total=False): + value: str + """The origin address you want to override with.""" + + +class ActionResolveOverride(TypedDict, total=False): + id: Literal["resolve_override"] + """Change the origin address to the value specified in this setting.""" + + value: ActionResolveOverrideValue + + +class ActionRespectStrongEtag(TypedDict, total=False): + id: Literal["respect_strong_etag"] + """ + Turn on or off byte-for-byte equivalency checks between the Cloudflare cache and + the origin server. + """ + + value: Literal["on", "off"] + """The status of Respect Strong ETags""" + + +Action: TypeAlias = Union[ + AlwaysUseHTTPSParam, + AutomaticHTTPSRewritesParam, + BrowserCacheTTLParam, + BrowserCheckParam, + ActionBypassCacheOnCookie, + ActionCacheByDeviceType, + ActionCacheDeceptionArmor, + ActionCacheKey, + ActionCacheKeyFields, + CacheLevelParam, + ActionCacheOnCookie, + ActionCacheTTLByStatus, + ActionDDoSProtection, + DevelopmentModeParam, + ActionDisableApps, + ActionDisablePerformance, + ActionDisableSecurity, + ActionDisableZaraz, + ActionEdgeCacheTTL, + EmailObfuscationParam, + ActionExplicitCacheControl, + ActionForwardingURL, + ActionHostHeaderOverride, + HotlinkProtectionParam, + IPGeolocationParam, + ActionMinify, + MirageParam, + OpportunisticEncryptionParam, + OriginErrorPagePassThruParam, + PolishParam, + ActionPurgeByPageRule, + ActionResolveOverride, + ActionRespectStrongEtag, + ResponseBufferingParam, + RocketLoaderParam, + SecurityLevelParam, + ServerSideExcludesParam, + SortQueryStringForCacheParam, + SSLParam, + TrueClientIPHeaderParam, + WAFParam, +] diff --git a/src/cloudflare/types/rate_limits/__init__.py b/src/cloudflare/types/rate_limits/__init__.py index 4a096a81acd..3a9129f1e6e 100644 --- a/src/cloudflare/types/rate_limits/__init__.py +++ b/src/cloudflare/types/rate_limits/__init__.py @@ -4,3 +4,8 @@ from .action import Action as Action from .methods import Methods as Methods +from .rate_limit import RateLimit as RateLimit +from .rate_limit_edit_params import RateLimitEditParams as RateLimitEditParams +from .rate_limit_list_params import RateLimitListParams as RateLimitListParams +from .rate_limit_create_params import RateLimitCreateParams as RateLimitCreateParams +from .rate_limit_delete_response import RateLimitDeleteResponse as RateLimitDeleteResponse diff --git a/src/cloudflare/types/rate_limits/rate_limit.py b/src/cloudflare/types/rate_limits/rate_limit.py new file mode 100644 index 00000000000..9fa5741af1a --- /dev/null +++ b/src/cloudflare/types/rate_limits/rate_limit.py @@ -0,0 +1,150 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from .methods import Methods +from ..._models import BaseModel + +__all__ = ["RateLimit", "Action", "ActionResponse", "Bypass", "Match", "MatchHeader", "MatchRequest", "MatchResponse"] + + +class ActionResponse(BaseModel): + body: Optional[str] = None + """The response body to return. + + The value must conform to the configured content type. + """ + + content_type: Optional[str] = None + """The content type of the body. + + Must be one of the following: `text/plain`, `text/xml`, or `application/json`. + """ + + +class Action(BaseModel): + mode: Optional[Literal["simulate", "ban", "challenge", "js_challenge", "managed_challenge"]] = None + """The action to perform.""" + + response: Optional[ActionResponse] = None + """A custom content type and reponse to return when the threshold is exceeded. + + The custom response configured in this object will override the custom error for + the zone. This object is optional. Notes: If you omit this object, Cloudflare + will use the default HTML error page. If "mode" is "challenge", + "managed_challenge", or "js_challenge", Cloudflare will use the zone challenge + pages and you should not provide the "response" object. + """ + + timeout: Optional[float] = None + """The time in seconds during which Cloudflare will perform the mitigation action. + + Must be an integer value greater than or equal to the period. Notes: If "mode" + is "challenge", "managed_challenge", or "js_challenge", Cloudflare will use the + zone's Challenge Passage time and you should not provide this value. + """ + + +class Bypass(BaseModel): + name: Optional[Literal["url"]] = None + + value: Optional[str] = None + """The URL to bypass.""" + + +class MatchHeader(BaseModel): + name: Optional[str] = None + """The name of the response header to match.""" + + op: Optional[Literal["eq", "ne"]] = None + """The operator used when matching: `eq` means "equal" and `ne` means "not equal".""" + + value: Optional[str] = None + """The value of the response header, which must match exactly.""" + + +class MatchRequest(BaseModel): + methods: Optional[List[Methods]] = None + """The HTTP methods to match. + + You can specify a subset (for example, `['POST','PUT']`) or all methods + (`['_ALL_']`). This field is optional when creating a rate limit. + """ + + schemes: Optional[List[str]] = None + """The HTTP schemes to match. + + You can specify one scheme (`['HTTPS']`), both schemes (`['HTTP','HTTPS']`), or + all schemes (`['_ALL_']`). This field is optional. + """ + + url: Optional[str] = None + """ + The URL pattern to match, composed of a host and a path such as + `example.org/path*`. Normalization is applied before the pattern is matched. `*` + wildcards are expanded to match applicable traffic. Query strings are not + matched. Set the value to `*` to match all traffic to your zone. + """ + + +class MatchResponse(BaseModel): + origin_traffic: Optional[bool] = None + """ + When true, only the uncached traffic served from your origin servers will count + towards rate limiting. In this case, any cached traffic served by Cloudflare + will not count towards rate limiting. This field is optional. Notes: This field + is deprecated. Instead, use response headers and set "origin_traffic" to "false" + to avoid legacy behaviour interacting with the "response_headers" property. + """ + + +class Match(BaseModel): + headers: Optional[List[MatchHeader]] = None + + request: Optional[MatchRequest] = None + + response: Optional[MatchResponse] = None + + +class RateLimit(BaseModel): + id: Optional[str] = None + """The unique identifier of the rate limit.""" + + action: Optional[Action] = None + """ + The action to perform when the threshold of matched traffic within the + configured period is exceeded. + """ + + bypass: Optional[List[Bypass]] = None + """Criteria specifying when the current rate limit should be bypassed. + + You can specify that the rate limit should not apply to one or more URLs. + """ + + description: Optional[str] = None + """An informative summary of the rate limit. + + This value is sanitized and any tags will be removed. + """ + + disabled: Optional[bool] = None + """When true, indicates that the rate limit is currently disabled.""" + + match: Optional[Match] = None + """Determines which traffic the rate limit counts towards the threshold.""" + + period: Optional[float] = None + """The time in seconds (an integer value) to count matching traffic. + + If the count exceeds the configured threshold within this period, Cloudflare + will perform the configured action. + """ + + threshold: Optional[float] = None + """The threshold that will trigger the configured mitigation action. + + Configure this value along with the `period` property to establish a threshold + per period. + """ diff --git a/src/cloudflare/types/rate_limits/rate_limit_create_params.py b/src/cloudflare/types/rate_limits/rate_limit_create_params.py new file mode 100644 index 00000000000..e4f35081a32 --- /dev/null +++ b/src/cloudflare/types/rate_limits/rate_limit_create_params.py @@ -0,0 +1,129 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Iterable +from typing_extensions import Literal, Required, TypedDict + +from .methods import Methods + +__all__ = ["RateLimitCreateParams", "Action", "ActionResponse", "Match", "MatchHeader", "MatchRequest", "MatchResponse"] + + +class RateLimitCreateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + action: Required[Action] + """ + The action to perform when the threshold of matched traffic within the + configured period is exceeded. + """ + + match: Required[Match] + """Determines which traffic the rate limit counts towards the threshold.""" + + period: Required[float] + """The time in seconds (an integer value) to count matching traffic. + + If the count exceeds the configured threshold within this period, Cloudflare + will perform the configured action. + """ + + threshold: Required[float] + """The threshold that will trigger the configured mitigation action. + + Configure this value along with the `period` property to establish a threshold + per period. + """ + + +class ActionResponse(TypedDict, total=False): + body: str + """The response body to return. + + The value must conform to the configured content type. + """ + + content_type: str + """The content type of the body. + + Must be one of the following: `text/plain`, `text/xml`, or `application/json`. + """ + + +class Action(TypedDict, total=False): + mode: Literal["simulate", "ban", "challenge", "js_challenge", "managed_challenge"] + """The action to perform.""" + + response: ActionResponse + """A custom content type and reponse to return when the threshold is exceeded. + + The custom response configured in this object will override the custom error for + the zone. This object is optional. Notes: If you omit this object, Cloudflare + will use the default HTML error page. If "mode" is "challenge", + "managed_challenge", or "js_challenge", Cloudflare will use the zone challenge + pages and you should not provide the "response" object. + """ + + timeout: float + """The time in seconds during which Cloudflare will perform the mitigation action. + + Must be an integer value greater than or equal to the period. Notes: If "mode" + is "challenge", "managed_challenge", or "js_challenge", Cloudflare will use the + zone's Challenge Passage time and you should not provide this value. + """ + + +class MatchHeader(TypedDict, total=False): + name: str + """The name of the response header to match.""" + + op: Literal["eq", "ne"] + """The operator used when matching: `eq` means "equal" and `ne` means "not equal".""" + + value: str + """The value of the response header, which must match exactly.""" + + +class MatchRequest(TypedDict, total=False): + methods: List[Methods] + """The HTTP methods to match. + + You can specify a subset (for example, `['POST','PUT']`) or all methods + (`['_ALL_']`). This field is optional when creating a rate limit. + """ + + schemes: List[str] + """The HTTP schemes to match. + + You can specify one scheme (`['HTTPS']`), both schemes (`['HTTP','HTTPS']`), or + all schemes (`['_ALL_']`). This field is optional. + """ + + url: str + """ + The URL pattern to match, composed of a host and a path such as + `example.org/path*`. Normalization is applied before the pattern is matched. `*` + wildcards are expanded to match applicable traffic. Query strings are not + matched. Set the value to `*` to match all traffic to your zone. + """ + + +class MatchResponse(TypedDict, total=False): + origin_traffic: bool + """ + When true, only the uncached traffic served from your origin servers will count + towards rate limiting. In this case, any cached traffic served by Cloudflare + will not count towards rate limiting. This field is optional. Notes: This field + is deprecated. Instead, use response headers and set "origin_traffic" to "false" + to avoid legacy behaviour interacting with the "response_headers" property. + """ + + +class Match(TypedDict, total=False): + headers: Iterable[MatchHeader] + + request: MatchRequest + + response: MatchResponse diff --git a/src/cloudflare/types/rate_limits/rate_limit_delete_response.py b/src/cloudflare/types/rate_limits/rate_limit_delete_response.py new file mode 100644 index 00000000000..380d71356ee --- /dev/null +++ b/src/cloudflare/types/rate_limits/rate_limit_delete_response.py @@ -0,0 +1,159 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from .methods import Methods +from ..._models import BaseModel + +__all__ = [ + "RateLimitDeleteResponse", + "Action", + "ActionResponse", + "Bypass", + "Match", + "MatchHeader", + "MatchRequest", + "MatchResponse", +] + + +class ActionResponse(BaseModel): + body: Optional[str] = None + """The response body to return. + + The value must conform to the configured content type. + """ + + content_type: Optional[str] = None + """The content type of the body. + + Must be one of the following: `text/plain`, `text/xml`, or `application/json`. + """ + + +class Action(BaseModel): + mode: Optional[Literal["simulate", "ban", "challenge", "js_challenge", "managed_challenge"]] = None + """The action to perform.""" + + response: Optional[ActionResponse] = None + """A custom content type and reponse to return when the threshold is exceeded. + + The custom response configured in this object will override the custom error for + the zone. This object is optional. Notes: If you omit this object, Cloudflare + will use the default HTML error page. If "mode" is "challenge", + "managed_challenge", or "js_challenge", Cloudflare will use the zone challenge + pages and you should not provide the "response" object. + """ + + timeout: Optional[float] = None + """The time in seconds during which Cloudflare will perform the mitigation action. + + Must be an integer value greater than or equal to the period. Notes: If "mode" + is "challenge", "managed_challenge", or "js_challenge", Cloudflare will use the + zone's Challenge Passage time and you should not provide this value. + """ + + +class Bypass(BaseModel): + name: Optional[Literal["url"]] = None + + value: Optional[str] = None + """The URL to bypass.""" + + +class MatchHeader(BaseModel): + name: Optional[str] = None + """The name of the response header to match.""" + + op: Optional[Literal["eq", "ne"]] = None + """The operator used when matching: `eq` means "equal" and `ne` means "not equal".""" + + value: Optional[str] = None + """The value of the response header, which must match exactly.""" + + +class MatchRequest(BaseModel): + methods: Optional[List[Methods]] = None + """The HTTP methods to match. + + You can specify a subset (for example, `['POST','PUT']`) or all methods + (`['_ALL_']`). This field is optional when creating a rate limit. + """ + + schemes: Optional[List[str]] = None + """The HTTP schemes to match. + + You can specify one scheme (`['HTTPS']`), both schemes (`['HTTP','HTTPS']`), or + all schemes (`['_ALL_']`). This field is optional. + """ + + url: Optional[str] = None + """ + The URL pattern to match, composed of a host and a path such as + `example.org/path*`. Normalization is applied before the pattern is matched. `*` + wildcards are expanded to match applicable traffic. Query strings are not + matched. Set the value to `*` to match all traffic to your zone. + """ + + +class MatchResponse(BaseModel): + origin_traffic: Optional[bool] = None + """ + When true, only the uncached traffic served from your origin servers will count + towards rate limiting. In this case, any cached traffic served by Cloudflare + will not count towards rate limiting. This field is optional. Notes: This field + is deprecated. Instead, use response headers and set "origin_traffic" to "false" + to avoid legacy behaviour interacting with the "response_headers" property. + """ + + +class Match(BaseModel): + headers: Optional[List[MatchHeader]] = None + + request: Optional[MatchRequest] = None + + response: Optional[MatchResponse] = None + + +class RateLimitDeleteResponse(BaseModel): + id: Optional[str] = None + """The unique identifier of the rate limit.""" + + action: Optional[Action] = None + """ + The action to perform when the threshold of matched traffic within the + configured period is exceeded. + """ + + bypass: Optional[List[Bypass]] = None + """Criteria specifying when the current rate limit should be bypassed. + + You can specify that the rate limit should not apply to one or more URLs. + """ + + description: Optional[str] = None + """An informative summary of the rate limit. + + This value is sanitized and any tags will be removed. + """ + + disabled: Optional[bool] = None + """When true, indicates that the rate limit is currently disabled.""" + + match: Optional[Match] = None + """Determines which traffic the rate limit counts towards the threshold.""" + + period: Optional[float] = None + """The time in seconds (an integer value) to count matching traffic. + + If the count exceeds the configured threshold within this period, Cloudflare + will perform the configured action. + """ + + threshold: Optional[float] = None + """The threshold that will trigger the configured mitigation action. + + Configure this value along with the `period` property to establish a threshold + per period. + """ diff --git a/src/cloudflare/types/rate_limits/rate_limit_edit_params.py b/src/cloudflare/types/rate_limits/rate_limit_edit_params.py new file mode 100644 index 00000000000..3358bb60c93 --- /dev/null +++ b/src/cloudflare/types/rate_limits/rate_limit_edit_params.py @@ -0,0 +1,129 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Iterable +from typing_extensions import Literal, Required, TypedDict + +from .methods import Methods + +__all__ = ["RateLimitEditParams", "Action", "ActionResponse", "Match", "MatchHeader", "MatchRequest", "MatchResponse"] + + +class RateLimitEditParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + action: Required[Action] + """ + The action to perform when the threshold of matched traffic within the + configured period is exceeded. + """ + + match: Required[Match] + """Determines which traffic the rate limit counts towards the threshold.""" + + period: Required[float] + """The time in seconds (an integer value) to count matching traffic. + + If the count exceeds the configured threshold within this period, Cloudflare + will perform the configured action. + """ + + threshold: Required[float] + """The threshold that will trigger the configured mitigation action. + + Configure this value along with the `period` property to establish a threshold + per period. + """ + + +class ActionResponse(TypedDict, total=False): + body: str + """The response body to return. + + The value must conform to the configured content type. + """ + + content_type: str + """The content type of the body. + + Must be one of the following: `text/plain`, `text/xml`, or `application/json`. + """ + + +class Action(TypedDict, total=False): + mode: Literal["simulate", "ban", "challenge", "js_challenge", "managed_challenge"] + """The action to perform.""" + + response: ActionResponse + """A custom content type and reponse to return when the threshold is exceeded. + + The custom response configured in this object will override the custom error for + the zone. This object is optional. Notes: If you omit this object, Cloudflare + will use the default HTML error page. If "mode" is "challenge", + "managed_challenge", or "js_challenge", Cloudflare will use the zone challenge + pages and you should not provide the "response" object. + """ + + timeout: float + """The time in seconds during which Cloudflare will perform the mitigation action. + + Must be an integer value greater than or equal to the period. Notes: If "mode" + is "challenge", "managed_challenge", or "js_challenge", Cloudflare will use the + zone's Challenge Passage time and you should not provide this value. + """ + + +class MatchHeader(TypedDict, total=False): + name: str + """The name of the response header to match.""" + + op: Literal["eq", "ne"] + """The operator used when matching: `eq` means "equal" and `ne` means "not equal".""" + + value: str + """The value of the response header, which must match exactly.""" + + +class MatchRequest(TypedDict, total=False): + methods: List[Methods] + """The HTTP methods to match. + + You can specify a subset (for example, `['POST','PUT']`) or all methods + (`['_ALL_']`). This field is optional when creating a rate limit. + """ + + schemes: List[str] + """The HTTP schemes to match. + + You can specify one scheme (`['HTTPS']`), both schemes (`['HTTP','HTTPS']`), or + all schemes (`['_ALL_']`). This field is optional. + """ + + url: str + """ + The URL pattern to match, composed of a host and a path such as + `example.org/path*`. Normalization is applied before the pattern is matched. `*` + wildcards are expanded to match applicable traffic. Query strings are not + matched. Set the value to `*` to match all traffic to your zone. + """ + + +class MatchResponse(TypedDict, total=False): + origin_traffic: bool + """ + When true, only the uncached traffic served from your origin servers will count + towards rate limiting. In this case, any cached traffic served by Cloudflare + will not count towards rate limiting. This field is optional. Notes: This field + is deprecated. Instead, use response headers and set "origin_traffic" to "false" + to avoid legacy behaviour interacting with the "response_headers" property. + """ + + +class Match(TypedDict, total=False): + headers: Iterable[MatchHeader] + + request: MatchRequest + + response: MatchResponse diff --git a/src/cloudflare/types/rate_limits/rate_limit_list_params.py b/src/cloudflare/types/rate_limits/rate_limit_list_params.py new file mode 100644 index 00000000000..4d9d72910be --- /dev/null +++ b/src/cloudflare/types/rate_limits/rate_limit_list_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RateLimitListParams"] + + +class RateLimitListParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier""" + + page: float + """The page number of paginated results.""" + + per_page: float + """The maximum number of results per page. + + You can only set the value to `1` or to a multiple of 5 such as `5`, `10`, `15`, + or `20`. + """ diff --git a/src/cloudflare/types/zones/__init__.py b/src/cloudflare/types/zones/__init__.py index b8e90f5ed1f..656aeb26d5b 100644 --- a/src/cloudflare/types/zones/__init__.py +++ b/src/cloudflare/types/zones/__init__.py @@ -17,11 +17,15 @@ from .ciphers import Ciphers as Ciphers from .tls_1_3 import TLS1_3 as TLS1_3 from .zero_rtt import ZeroRTT as ZeroRTT +from .ssl_param import SSLParam as SSLParam +from .waf_param import WAFParam as WAFParam from .websocket import Websocket as Websocket from .zone_hold import ZoneHold as ZoneHold from .cache_level import CacheLevel as CacheLevel from .early_hints import EarlyHints as EarlyHints from .pseudo_ipv4 import PseudoIPV4 as PseudoIPV4 +from .mirage_param import MirageParam as MirageParam +from .polish_param import PolishParam as PolishParam from .advanced_ddos import AdvancedDDoS as AdvancedDDoS from .always_online import AlwaysOnline as AlwaysOnline from .browser_check import BrowserCheck as BrowserCheck @@ -41,6 +45,7 @@ from .zone_edit_params import ZoneEditParams as ZoneEditParams from .zone_list_params import ZoneListParams as ZoneListParams from .browser_cache_ttl import BrowserCacheTTL as BrowserCacheTTL +from .cache_level_param import CacheLevelParam as CacheLevelParam from .email_obfuscation import EmailObfuscation as EmailObfuscation from .h2_prioritization import H2Prioritization as H2Prioritization from .hold_create_params import HoldCreateParams as HoldCreateParams @@ -50,29 +55,45 @@ from .response_buffering import ResponseBuffering as ResponseBuffering from .zone_create_params import ZoneCreateParams as ZoneCreateParams from .available_rate_plan import AvailableRatePlan as AvailableRatePlan +from .browser_check_param import BrowserCheckParam as BrowserCheckParam from .opportunistic_onion import OpportunisticOnion as OpportunisticOnion +from .rocket_loader_param import RocketLoaderParam as RocketLoaderParam from .setting_edit_params import SettingEditParams as SettingEditParams +from .ip_geolocation_param import IPGeolocationParam as IPGeolocationParam +from .security_level_param import SecurityLevelParam as SecurityLevelParam from .server_side_excludes import ServerSideExcludes as ServerSideExcludes from .setting_get_response import SettingGetResponse as SettingGetResponse from .zone_delete_response import ZoneDeleteResponse as ZoneDeleteResponse from .setting_edit_response import SettingEditResponse as SettingEditResponse from .true_client_ip_header import TrueClientIPHeader as TrueClientIPHeader +from .always_use_https_param import AlwaysUseHTTPSParam as AlwaysUseHTTPSParam +from .development_mode_param import DevelopmentModeParam as DevelopmentModeParam from .rate_plan_get_response import RatePlanGetResponse as RatePlanGetResponse +from .browser_cache_ttl_param import BrowserCacheTTLParam as BrowserCacheTTLParam +from .email_obfuscation_param import EmailObfuscationParam as EmailObfuscationParam from .origin_max_http_version import OriginMaxHTTPVersion as OriginMaxHTTPVersion from .automatic_https_rewrites import AutomaticHTTPSRewrites as AutomaticHTTPSRewrites +from .hotlink_protection_param import HotlinkProtectionParam as HotlinkProtectionParam from .opportunistic_encryption import OpportunisticEncryption as OpportunisticEncryption +from .response_buffering_param import ResponseBufferingParam as ResponseBufferingParam from .subscription_get_response import SubscriptionGetResponse as SubscriptionGetResponse +from .server_side_excludes_param import ServerSideExcludesParam as ServerSideExcludesParam from .subscription_create_params import SubscriptionCreateParams as SubscriptionCreateParams from .subscription_update_params import SubscriptionUpdateParams as SubscriptionUpdateParams from .origin_error_page_pass_thru import OriginErrorPagePassThru as OriginErrorPagePassThru from .sort_query_string_for_cache import SortQueryStringForCache as SortQueryStringForCache +from .true_client_ip_header_param import TrueClientIPHeaderParam as TrueClientIPHeaderParam from .subscription_create_response import SubscriptionCreateResponse as SubscriptionCreateResponse from .subscription_update_response import SubscriptionUpdateResponse as SubscriptionUpdateResponse +from .automatic_https_rewrites_param import AutomaticHTTPSRewritesParam as AutomaticHTTPSRewritesParam from .custom_nameserver_get_response import CustomNameserverGetResponse as CustomNameserverGetResponse +from .opportunistic_encryption_param import OpportunisticEncryptionParam as OpportunisticEncryptionParam from .automatic_platform_optimization import AutomaticPlatformOptimization as AutomaticPlatformOptimization from .custom_nameserver_update_params import CustomNameserverUpdateParams as CustomNameserverUpdateParams from .activation_check_trigger_response import ActivationCheckTriggerResponse as ActivationCheckTriggerResponse from .custom_nameserver_update_response import CustomNameserverUpdateResponse as CustomNameserverUpdateResponse +from .origin_error_page_pass_thru_param import OriginErrorPagePassThruParam as OriginErrorPagePassThruParam +from .sort_query_string_for_cache_param import SortQueryStringForCacheParam as SortQueryStringForCacheParam from .automatic_platform_optimization_param import ( AutomaticPlatformOptimizationParam as AutomaticPlatformOptimizationParam, ) diff --git a/src/cloudflare/types/zones/always_use_https.py b/src/cloudflare/types/zones/always_use_https.py index 78f176711aa..5adb357001b 100644 --- a/src/cloudflare/types/zones/always_use_https.py +++ b/src/cloudflare/types/zones/always_use_https.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,8 @@ class AlwaysUseHTTPS(BaseModel): - id: Literal["always_use_https"] - """ID of the zone setting.""" - - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None + id: Optional[Literal["always_use_https"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + If enabled, any ` http://`` URL is converted to `https://` through a 301 + redirect. """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" diff --git a/src/cloudflare/types/zones/always_use_https_param.py b/src/cloudflare/types/zones/always_use_https_param.py new file mode 100644 index 00000000000..9853d49bf7d --- /dev/null +++ b/src/cloudflare/types/zones/always_use_https_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["AlwaysUseHTTPSParam"] + + +class AlwaysUseHTTPSParam(TypedDict, total=False): + id: Literal["always_use_https"] + """ + If enabled, any ` http://`` URL is converted to `https://` through a 301 + redirect. + """ diff --git a/src/cloudflare/types/zones/automatic_https_rewrites.py b/src/cloudflare/types/zones/automatic_https_rewrites.py index ced7a3e50f5..9ca12b86aa3 100644 --- a/src/cloudflare/types/zones/automatic_https_rewrites.py +++ b/src/cloudflare/types/zones/automatic_https_rewrites.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,4 @@ class AutomaticHTTPSRewrites(BaseModel): - id: Literal["automatic_https_rewrites"] - """ID of the zone setting.""" - - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + id: Optional[Literal["automatic_https_rewrites"]] = None diff --git a/src/cloudflare/types/zones/automatic_https_rewrites_param.py b/src/cloudflare/types/zones/automatic_https_rewrites_param.py new file mode 100644 index 00000000000..2435ed975b2 --- /dev/null +++ b/src/cloudflare/types/zones/automatic_https_rewrites_param.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["AutomaticHTTPSRewritesParam"] + + +class AutomaticHTTPSRewritesParam(TypedDict, total=False): + id: Literal["automatic_https_rewrites"] diff --git a/src/cloudflare/types/zones/browser_cache_ttl.py b/src/cloudflare/types/zones/browser_cache_ttl.py index 77393c400dc..35d15b7fabf 100644 --- a/src/cloudflare/types/zones/browser_cache_ttl.py +++ b/src/cloudflare/types/zones/browser_cache_ttl.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,46 +9,11 @@ class BrowserCacheTTL(BaseModel): - id: Literal["browser_cache_ttl"] - """ID of the zone setting.""" + id: Optional[Literal["browser_cache_ttl"]] = None + """Control how long resources cached by client browsers remain valid.""" - value: Literal[ - 0, - 30, - 60, - 120, - 300, - 1200, - 1800, - 3600, - 7200, - 10800, - 14400, - 18000, - 28800, - 43200, - 57600, - 72000, - 86400, - 172800, - 259200, - 345600, - 432000, - 691200, - 1382400, - 2073600, - 2678400, - 5356800, - 16070400, - 31536000, - ] - """Current value of the zone setting.""" + value: Optional[int] = None + """The number of seconds to cache resources for. - editable: Optional[Literal[True, False]] = None + The API prohibits setting this to 0 for non-Enterprise domains. """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" diff --git a/src/cloudflare/types/zones/browser_cache_ttl_param.py b/src/cloudflare/types/zones/browser_cache_ttl_param.py new file mode 100644 index 00000000000..acf9e43b4ec --- /dev/null +++ b/src/cloudflare/types/zones/browser_cache_ttl_param.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["BrowserCacheTTLParam"] + + +class BrowserCacheTTLParam(TypedDict, total=False): + id: Literal["browser_cache_ttl"] + """Control how long resources cached by client browsers remain valid.""" + + value: int + """The number of seconds to cache resources for. + + The API prohibits setting this to 0 for non-Enterprise domains. + """ diff --git a/src/cloudflare/types/zones/browser_check.py b/src/cloudflare/types/zones/browser_check.py index 9de5013bcaa..79c5d1e6a8b 100644 --- a/src/cloudflare/types/zones/browser_check.py +++ b/src/cloudflare/types/zones/browser_check.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,11 @@ class BrowserCheck(BaseModel): - id: Literal["browser_check"] - """ID of the zone setting.""" - - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None + id: Optional[Literal["browser_check"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Inspect the visitor's browser for headers commonly associated with spammers and + certain bots. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Literal["on", "off"]] = None + """The status of Browser Integrity Check.""" diff --git a/src/cloudflare/types/zones/browser_check_param.py b/src/cloudflare/types/zones/browser_check_param.py new file mode 100644 index 00000000000..ffe14ebb557 --- /dev/null +++ b/src/cloudflare/types/zones/browser_check_param.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["BrowserCheckParam"] + + +class BrowserCheckParam(TypedDict, total=False): + id: Literal["browser_check"] + """ + Inspect the visitor's browser for headers commonly associated with spammers and + certain bots. + """ + + value: Literal["on", "off"] + """The status of Browser Integrity Check.""" diff --git a/src/cloudflare/types/zones/cache_level.py b/src/cloudflare/types/zones/cache_level.py index 7aaf4433499..06e02c2fb2d 100644 --- a/src/cloudflare/types/zones/cache_level.py +++ b/src/cloudflare/types/zones/cache_level.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,17 @@ class CacheLevel(BaseModel): - id: Literal["cache_level"] - """ID of the zone setting.""" + id: Optional[Literal["cache_level"]] = None + """Apply custom caching based on the option selected.""" - value: Literal["aggressive", "basic", "simplified"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None + value: Optional[Literal["bypass", "basic", "simplified", "aggressive", "cache_everything"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + - `bypass`: Cloudflare does not cache. + - `basic`: Delivers resources from cache when there is no query string. + - `simplified`: Delivers the same resource to everyone independent of the query + string. + - `aggressive`: Caches all static content that has a query string. + - `cache_everything`: Treats all content as static and caches all file types + beyond the + [Cloudflare default cached content](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions). """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" diff --git a/src/cloudflare/types/zones/cache_level_param.py b/src/cloudflare/types/zones/cache_level_param.py new file mode 100644 index 00000000000..daa1406ae4b --- /dev/null +++ b/src/cloudflare/types/zones/cache_level_param.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["CacheLevelParam"] + + +class CacheLevelParam(TypedDict, total=False): + id: Literal["cache_level"] + """Apply custom caching based on the option selected.""" + + value: Literal["bypass", "basic", "simplified", "aggressive", "cache_everything"] + """ + - `bypass`: Cloudflare does not cache. + - `basic`: Delivers resources from cache when there is no query string. + - `simplified`: Delivers the same resource to everyone independent of the query + string. + - `aggressive`: Caches all static content that has a query string. + - `cache_everything`: Treats all content as static and caches all file types + beyond the + [Cloudflare default cached content](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions). + """ diff --git a/src/cloudflare/types/zones/development_mode.py b/src/cloudflare/types/zones/development_mode.py index 06c81d58b5f..f529e46ab04 100644 --- a/src/cloudflare/types/zones/development_mode.py +++ b/src/cloudflare/types/zones/development_mode.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,24 +9,4 @@ class DevelopmentMode(BaseModel): - id: Literal["development_mode"] - """ID of the zone setting.""" - - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" - - time_remaining: Optional[float] = None - """ - Value of the zone setting. Notes: The interval (in seconds) from when - development mode expires (positive integer) or last expired (negative integer) - for the domain. If development mode has never been enabled, this value is false. - """ + id: Optional[Literal["development_mode"]] = None diff --git a/src/cloudflare/types/zones/development_mode_param.py b/src/cloudflare/types/zones/development_mode_param.py new file mode 100644 index 00000000000..83e95df5c1c --- /dev/null +++ b/src/cloudflare/types/zones/development_mode_param.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["DevelopmentModeParam"] + + +class DevelopmentModeParam(TypedDict, total=False): + id: Literal["development_mode"] diff --git a/src/cloudflare/types/zones/email_obfuscation.py b/src/cloudflare/types/zones/email_obfuscation.py index 37ecaca46de..07ff01d4431 100644 --- a/src/cloudflare/types/zones/email_obfuscation.py +++ b/src/cloudflare/types/zones/email_obfuscation.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,8 @@ class EmailObfuscation(BaseModel): - id: Literal["email_obfuscation"] - """ID of the zone setting.""" + id: Optional[Literal["email_obfuscation"]] = None + """Turn on or off **Email Obfuscation**.""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Literal["on", "off"]] = None + """The status of Email Obfuscation.""" diff --git a/src/cloudflare/types/zones/email_obfuscation_param.py b/src/cloudflare/types/zones/email_obfuscation_param.py new file mode 100644 index 00000000000..e983e18c207 --- /dev/null +++ b/src/cloudflare/types/zones/email_obfuscation_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["EmailObfuscationParam"] + + +class EmailObfuscationParam(TypedDict, total=False): + id: Literal["email_obfuscation"] + """Turn on or off **Email Obfuscation**.""" + + value: Literal["on", "off"] + """The status of Email Obfuscation.""" diff --git a/src/cloudflare/types/zones/hotlink_protection.py b/src/cloudflare/types/zones/hotlink_protection.py index 45d990193de..54e60d05aab 100644 --- a/src/cloudflare/types/zones/hotlink_protection.py +++ b/src/cloudflare/types/zones/hotlink_protection.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,4 @@ class HotlinkProtection(BaseModel): - id: Literal["hotlink_protection"] - """ID of the zone setting.""" - - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + id: Optional[Literal["hotlink_protection"]] = None diff --git a/src/cloudflare/types/zones/hotlink_protection_param.py b/src/cloudflare/types/zones/hotlink_protection_param.py new file mode 100644 index 00000000000..cffd76c7102 --- /dev/null +++ b/src/cloudflare/types/zones/hotlink_protection_param.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["HotlinkProtectionParam"] + + +class HotlinkProtectionParam(TypedDict, total=False): + id: Literal["hotlink_protection"] diff --git a/src/cloudflare/types/zones/ip_geolocation.py b/src/cloudflare/types/zones/ip_geolocation.py index 0c378a4acc9..058549a5597 100644 --- a/src/cloudflare/types/zones/ip_geolocation.py +++ b/src/cloudflare/types/zones/ip_geolocation.py @@ -1,26 +1,23 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["IPGeolocation"] +__all__ = ["IPGeolocation", "Value"] -class IPGeolocation(BaseModel): - id: Literal["ip_geolocation"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["on", "off"]] = None + """The status of adding the IP Geolocation Header.""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None +class IPGeolocation(BaseModel): + id: Optional[Literal["ip_geolocation"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Cloudflare adds a CF-IPCountry HTTP header containing the country code that + corresponds to the visitor. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/ip_geolocation_param.py b/src/cloudflare/types/zones/ip_geolocation_param.py new file mode 100644 index 00000000000..66cfd4f605e --- /dev/null +++ b/src/cloudflare/types/zones/ip_geolocation_param.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["IPGeolocationParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["on", "off"] + """The status of adding the IP Geolocation Header.""" + + +class IPGeolocationParam(TypedDict, total=False): + id: Literal["ip_geolocation"] + """ + Cloudflare adds a CF-IPCountry HTTP header containing the country code that + corresponds to the visitor. + """ + + value: Value diff --git a/src/cloudflare/types/zones/mirage.py b/src/cloudflare/types/zones/mirage.py index 4679cc48ebb..51f593c6dea 100644 --- a/src/cloudflare/types/zones/mirage.py +++ b/src/cloudflare/types/zones/mirage.py @@ -1,26 +1,24 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["Mirage"] +__all__ = ["Mirage", "Value"] -class Mirage(BaseModel): - id: Literal["mirage"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["on", "off"]] = None + """The status of Mirage.""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None +class Mirage(BaseModel): + id: Optional[Literal["mirage"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Cloudflare Mirage reduces bandwidth used by images in mobile browsers. It can + accelerate loading of image-heavy websites on very slow mobile connections and + HTTP/1. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/mirage_param.py b/src/cloudflare/types/zones/mirage_param.py new file mode 100644 index 00000000000..f9614642524 --- /dev/null +++ b/src/cloudflare/types/zones/mirage_param.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["MirageParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["on", "off"] + """The status of Mirage.""" + + +class MirageParam(TypedDict, total=False): + id: Literal["mirage"] + """ + Cloudflare Mirage reduces bandwidth used by images in mobile browsers. It can + accelerate loading of image-heavy websites on very slow mobile connections and + HTTP/1. + """ + + value: Value diff --git a/src/cloudflare/types/zones/opportunistic_encryption.py b/src/cloudflare/types/zones/opportunistic_encryption.py index 7ab0d1e8275..fb1d5f99bb4 100644 --- a/src/cloudflare/types/zones/opportunistic_encryption.py +++ b/src/cloudflare/types/zones/opportunistic_encryption.py @@ -1,26 +1,24 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["OpportunisticEncryption"] +__all__ = ["OpportunisticEncryption", "Value"] -class OpportunisticEncryption(BaseModel): - id: Literal["opportunistic_encryption"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["on", "off"]] = None + """The status of Opportunistic Encryption.""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None +class OpportunisticEncryption(BaseModel): + id: Optional[Literal["opportunistic_encryption"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Opportunistic Encryption allows browsers to access HTTP URIs over an encrypted + TLS channel. It's not a substitute for HTTPS, but provides additional security + for otherwise vulnerable requests. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/opportunistic_encryption_param.py b/src/cloudflare/types/zones/opportunistic_encryption_param.py new file mode 100644 index 00000000000..389ee32da9c --- /dev/null +++ b/src/cloudflare/types/zones/opportunistic_encryption_param.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["OpportunisticEncryptionParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["on", "off"] + """The status of Opportunistic Encryption.""" + + +class OpportunisticEncryptionParam(TypedDict, total=False): + id: Literal["opportunistic_encryption"] + """ + Opportunistic Encryption allows browsers to access HTTP URIs over an encrypted + TLS channel. It's not a substitute for HTTPS, but provides additional security + for otherwise vulnerable requests. + """ + + value: Value diff --git a/src/cloudflare/types/zones/origin_error_page_pass_thru.py b/src/cloudflare/types/zones/origin_error_page_pass_thru.py index 24cd47f546b..66f907452ef 100644 --- a/src/cloudflare/types/zones/origin_error_page_pass_thru.py +++ b/src/cloudflare/types/zones/origin_error_page_pass_thru.py @@ -1,26 +1,23 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["OriginErrorPagePassThru"] +__all__ = ["OriginErrorPagePassThru", "Value"] -class OriginErrorPagePassThru(BaseModel): - id: Literal["origin_error_page_pass_thru"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["on", "off"]] = None + """The status of Origin Error Page Passthru.""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None +class OriginErrorPagePassThru(BaseModel): + id: Optional[Literal["origin_error_page_pass_thru"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Turn on or off Cloudflare error pages generated from issues sent from the origin + server. If enabled, this setting triggers error pages issued by the origin. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/origin_error_page_pass_thru_param.py b/src/cloudflare/types/zones/origin_error_page_pass_thru_param.py new file mode 100644 index 00000000000..d423939e37a --- /dev/null +++ b/src/cloudflare/types/zones/origin_error_page_pass_thru_param.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["OriginErrorPagePassThruParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["on", "off"] + """The status of Origin Error Page Passthru.""" + + +class OriginErrorPagePassThruParam(TypedDict, total=False): + id: Literal["origin_error_page_pass_thru"] + """ + Turn on or off Cloudflare error pages generated from issues sent from the origin + server. If enabled, this setting triggers error pages issued by the origin. + """ + + value: Value diff --git a/src/cloudflare/types/zones/polish.py b/src/cloudflare/types/zones/polish.py index c75f4c9c129..46687b3e389 100644 --- a/src/cloudflare/types/zones/polish.py +++ b/src/cloudflare/types/zones/polish.py @@ -1,26 +1,20 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["Polish"] +__all__ = ["Polish", "Value"] -class Polish(BaseModel): - id: Literal["polish"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["off", "lossless", "lossy"]] = None + """The level of Polish you want applied to your origin.""" - value: Literal["off", "lossless", "lossy"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ +class Polish(BaseModel): + id: Optional[Literal["polish"]] = None + """Apply options from the Polish feature of the Cloudflare Speed app.""" - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/polish_param.py b/src/cloudflare/types/zones/polish_param.py new file mode 100644 index 00000000000..a24804b5132 --- /dev/null +++ b/src/cloudflare/types/zones/polish_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["PolishParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["off", "lossless", "lossy"] + """The level of Polish you want applied to your origin.""" + + +class PolishParam(TypedDict, total=False): + id: Literal["polish"] + """Apply options from the Polish feature of the Cloudflare Speed app.""" + + value: Value diff --git a/src/cloudflare/types/zones/response_buffering.py b/src/cloudflare/types/zones/response_buffering.py index cee36587e1a..840d27c0b0b 100644 --- a/src/cloudflare/types/zones/response_buffering.py +++ b/src/cloudflare/types/zones/response_buffering.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,12 @@ class ResponseBuffering(BaseModel): - id: Literal["response_buffering"] - """ID of the zone setting.""" - - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None + id: Optional[Literal["response_buffering"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Turn on or off whether Cloudflare should wait for an entire file from the origin + server before forwarding it to the site visitor. By default, Cloudflare sends + packets to the client as they arrive from the origin server. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Literal["on", "off"]] = None + """The status of Response Buffering""" diff --git a/src/cloudflare/types/zones/response_buffering_param.py b/src/cloudflare/types/zones/response_buffering_param.py new file mode 100644 index 00000000000..b144afd1917 --- /dev/null +++ b/src/cloudflare/types/zones/response_buffering_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["ResponseBufferingParam"] + + +class ResponseBufferingParam(TypedDict, total=False): + id: Literal["response_buffering"] + """ + Turn on or off whether Cloudflare should wait for an entire file from the origin + server before forwarding it to the site visitor. By default, Cloudflare sends + packets to the client as they arrive from the origin server. + """ + + value: Literal["on", "off"] + """The status of Response Buffering""" diff --git a/src/cloudflare/types/zones/rocket_loader.py b/src/cloudflare/types/zones/rocket_loader.py index 1fcbbd08bea..4ca3fff374a 100644 --- a/src/cloudflare/types/zones/rocket_loader.py +++ b/src/cloudflare/types/zones/rocket_loader.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,8 @@ class RocketLoader(BaseModel): - id: Literal["rocket_loader"] - """ID of the zone setting.""" + id: Optional[Literal["rocket_loader"]] = None + """Turn on or off Rocket Loader in the Cloudflare Speed app.""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Literal["on", "off"]] = None + """The status of Rocket Loader""" diff --git a/src/cloudflare/types/zones/rocket_loader_param.py b/src/cloudflare/types/zones/rocket_loader_param.py new file mode 100644 index 00000000000..385afbda75f --- /dev/null +++ b/src/cloudflare/types/zones/rocket_loader_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["RocketLoaderParam"] + + +class RocketLoaderParam(TypedDict, total=False): + id: Literal["rocket_loader"] + """Turn on or off Rocket Loader in the Cloudflare Speed app.""" + + value: Literal["on", "off"] + """The status of Rocket Loader""" diff --git a/src/cloudflare/types/zones/security_level.py b/src/cloudflare/types/zones/security_level.py index 93dfddc12ef..0adbeedbaaf 100644 --- a/src/cloudflare/types/zones/security_level.py +++ b/src/cloudflare/types/zones/security_level.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,7 @@ class SecurityLevel(BaseModel): - id: Literal["security_level"] - """ID of the zone setting.""" + id: Optional[Literal["security_level"]] = None + """Control options for the **Security Level** feature from the **Security** app.""" - value: Literal["off", "essentially_off", "low", "medium", "high", "under_attack"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Literal["off", "essentially_off", "low", "medium", "high", "under_attack"]] = None diff --git a/src/cloudflare/types/zones/security_level_param.py b/src/cloudflare/types/zones/security_level_param.py new file mode 100644 index 00000000000..ce4d8a4e0aa --- /dev/null +++ b/src/cloudflare/types/zones/security_level_param.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["SecurityLevelParam"] + + +class SecurityLevelParam(TypedDict, total=False): + id: Literal["security_level"] + """Control options for the **Security Level** feature from the **Security** app.""" + + value: Literal["off", "essentially_off", "low", "medium", "high", "under_attack"] diff --git a/src/cloudflare/types/zones/server_side_excludes.py b/src/cloudflare/types/zones/server_side_excludes.py index 2630a01b631..22a52497396 100644 --- a/src/cloudflare/types/zones/server_side_excludes.py +++ b/src/cloudflare/types/zones/server_side_excludes.py @@ -1,7 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel @@ -10,17 +9,4 @@ class ServerSideExcludes(BaseModel): - id: Literal["server_side_exclude"] - """ID of the zone setting.""" - - value: Literal["on", "off"] - """Current value of the zone setting.""" - - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ - - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + id: Optional[Literal["server_side_exclude"]] = None diff --git a/src/cloudflare/types/zones/server_side_excludes_param.py b/src/cloudflare/types/zones/server_side_excludes_param.py new file mode 100644 index 00000000000..1b0b716b61a --- /dev/null +++ b/src/cloudflare/types/zones/server_side_excludes_param.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["ServerSideExcludesParam"] + + +class ServerSideExcludesParam(TypedDict, total=False): + id: Literal["server_side_exclude"] diff --git a/src/cloudflare/types/zones/setting_edit_params.py b/src/cloudflare/types/zones/setting_edit_params.py index d42008fcbf6..c8225843385 100644 --- a/src/cloudflare/types/zones/setting_edit_params.py +++ b/src/cloudflare/types/zones/setting_edit_params.py @@ -12,57 +12,57 @@ "ZeroRTT", "AdvancedDDoS", "AlwaysOnline", - "AlwaysUseHTTPS", - "AutomaticHTTPSRewrites", + "ZonesSchemasAlwaysUseHTTPS", + "ZonesSchemasAutomaticHTTPSRewrites", "Brotli", - "BrowserCacheTTL", - "BrowserCheck", - "CacheLevel", + "ZonesSchemasBrowserCacheTTL", + "ZonesSchemasBrowserCheck", + "ZonesSchemasCacheLevel", "ChallengeTTL", "Ciphers", "ZonesCNAMEFlattening", - "DevelopmentMode", + "ZonesSchemasDevelopmentMode", "EarlyHints", - "ZonesEdgeCacheTTL", - "EmailObfuscation", + "ZonesSchemasEdgeCacheTTL", + "ZonesSchemasEmailObfuscation", "H2Prioritization", - "HotlinkProtection", + "ZonesSchemasHotlinkProtection", "HTTP2", "HTTP3", "ImageResizing", - "IPGeolocation", + "ZonesSchemasIPGeolocation", "IPV6", "ZonesMaxUpload", "MinTLSVersion", - "Mirage", + "ZonesSchemasMirage", "NEL", "NELValue", - "OpportunisticEncryption", + "ZonesSchemasOpportunisticEncryption", "OpportunisticOnion", "OrangeToOrange", - "OriginErrorPagePassThru", - "Polish", + "ZonesSchemasOriginErrorPagePassThru", + "ZonesSchemasPolish", "PrefetchPreload", "ProxyReadTimeout", "PseudoIPV4", "ZonesReplaceInsecureJS", - "ResponseBuffering", - "RocketLoader", + "ZonesSchemasResponseBuffering", + "ZonesSchemasRocketLoader", "ZonesSchemasAutomaticPlatformOptimization", "SecurityHeaders", "SecurityHeadersValue", "SecurityHeadersValueStrictTransportSecurity", - "SecurityLevel", - "ServerSideExcludes", + "ZonesSchemasSecurityLevel", + "ZonesSchemasServerSideExclude", "ZonesSha1Support", - "SortQueryStringForCache", - "SSL", + "ZonesSchemasSortQueryStringForCache", + "ZonesSchemasSSL", "SSLRecommender", "ZonesTLS1_2Only", "TLS1_3", "TLSClientAuth", - "TrueClientIPHeader", - "WAF", + "ZonesSchemasTrueClientIPHeader", + "ZonesSchemasWAF", "WebP", "Websocket", ] @@ -101,7 +101,7 @@ class AlwaysOnline(TypedDict, total=False): """Current value of the zone setting.""" -class AlwaysUseHTTPS(TypedDict, total=False): +class ZonesSchemasAlwaysUseHTTPS(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -112,7 +112,7 @@ class AlwaysUseHTTPS(TypedDict, total=False): """Current value of the zone setting.""" -class AutomaticHTTPSRewrites(TypedDict, total=False): +class ZonesSchemasAutomaticHTTPSRewrites(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -134,7 +134,7 @@ class Brotli(TypedDict, total=False): """Current value of the zone setting.""" -class BrowserCacheTTL(TypedDict, total=False): +class ZonesSchemasBrowserCacheTTL(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -176,7 +176,7 @@ class BrowserCacheTTL(TypedDict, total=False): """Current value of the zone setting.""" -class BrowserCheck(TypedDict, total=False): +class ZonesSchemasBrowserCheck(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -187,7 +187,7 @@ class BrowserCheck(TypedDict, total=False): """Current value of the zone setting.""" -class CacheLevel(TypedDict, total=False): +class ZonesSchemasCacheLevel(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -233,7 +233,7 @@ class ZonesCNAMEFlattening(TypedDict, total=False): """Current value of the zone setting.""" -class DevelopmentMode(TypedDict, total=False): +class ZonesSchemasDevelopmentMode(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -255,7 +255,7 @@ class EarlyHints(TypedDict, total=False): """Current value of the zone setting.""" -class ZonesEdgeCacheTTL(TypedDict, total=False): +class ZonesSchemasEdgeCacheTTL(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -290,7 +290,7 @@ class ZonesEdgeCacheTTL(TypedDict, total=False): """Current value of the zone setting.""" -class EmailObfuscation(TypedDict, total=False): +class ZonesSchemasEmailObfuscation(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -312,7 +312,7 @@ class H2Prioritization(TypedDict, total=False): """Current value of the zone setting.""" -class HotlinkProtection(TypedDict, total=False): +class ZonesSchemasHotlinkProtection(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -356,7 +356,7 @@ class ImageResizing(TypedDict, total=False): """Current value of the zone setting.""" -class IPGeolocation(TypedDict, total=False): +class ZonesSchemasIPGeolocation(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -400,7 +400,7 @@ class MinTLSVersion(TypedDict, total=False): """Current value of the zone setting.""" -class Mirage(TypedDict, total=False): +class ZonesSchemasMirage(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -426,7 +426,7 @@ class NELValue(TypedDict, total=False): enabled: bool -class OpportunisticEncryption(TypedDict, total=False): +class ZonesSchemasOpportunisticEncryption(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -459,7 +459,7 @@ class OrangeToOrange(TypedDict, total=False): """Current value of the zone setting.""" -class OriginErrorPagePassThru(TypedDict, total=False): +class ZonesSchemasOriginErrorPagePassThru(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -470,7 +470,7 @@ class OriginErrorPagePassThru(TypedDict, total=False): """Current value of the zone setting.""" -class Polish(TypedDict, total=False): +class ZonesSchemasPolish(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -525,7 +525,7 @@ class ZonesReplaceInsecureJS(TypedDict, total=False): """Current value of the zone setting.""" -class ResponseBuffering(TypedDict, total=False): +class ZonesSchemasResponseBuffering(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -536,7 +536,7 @@ class ResponseBuffering(TypedDict, total=False): """Current value of the zone setting.""" -class RocketLoader(TypedDict, total=False): +class ZonesSchemasRocketLoader(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -591,7 +591,7 @@ class SecurityHeadersValue(TypedDict, total=False): """Strict Transport Security.""" -class SecurityLevel(TypedDict, total=False): +class ZonesSchemasSecurityLevel(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -602,7 +602,7 @@ class SecurityLevel(TypedDict, total=False): """Current value of the zone setting.""" -class ServerSideExcludes(TypedDict, total=False): +class ZonesSchemasServerSideExclude(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -624,7 +624,7 @@ class ZonesSha1Support(TypedDict, total=False): """Current value of the zone setting.""" -class SortQueryStringForCache(TypedDict, total=False): +class ZonesSchemasSortQueryStringForCache(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -635,7 +635,7 @@ class SortQueryStringForCache(TypedDict, total=False): """Current value of the zone setting.""" -class SSL(TypedDict, total=False): +class ZonesSchemasSSL(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -690,7 +690,7 @@ class TLSClientAuth(TypedDict, total=False): """Current value of the zone setting.""" -class TrueClientIPHeader(TypedDict, total=False): +class ZonesSchemasTrueClientIPHeader(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -701,7 +701,7 @@ class TrueClientIPHeader(TypedDict, total=False): """Current value of the zone setting.""" -class WAF(TypedDict, total=False): +class ZonesSchemasWAF(TypedDict, total=False): zone_id: Required[str] """Identifier""" @@ -738,54 +738,54 @@ class Websocket(TypedDict, total=False): ZeroRTT, AdvancedDDoS, AlwaysOnline, - AlwaysUseHTTPS, - AutomaticHTTPSRewrites, + ZonesSchemasAlwaysUseHTTPS, + ZonesSchemasAutomaticHTTPSRewrites, Brotli, - BrowserCacheTTL, - BrowserCheck, - CacheLevel, + ZonesSchemasBrowserCacheTTL, + ZonesSchemasBrowserCheck, + ZonesSchemasCacheLevel, ChallengeTTL, Ciphers, ZonesCNAMEFlattening, - DevelopmentMode, + ZonesSchemasDevelopmentMode, EarlyHints, - ZonesEdgeCacheTTL, - EmailObfuscation, + ZonesSchemasEdgeCacheTTL, + ZonesSchemasEmailObfuscation, H2Prioritization, - HotlinkProtection, + ZonesSchemasHotlinkProtection, HTTP2, HTTP3, ImageResizing, - IPGeolocation, + ZonesSchemasIPGeolocation, IPV6, ZonesMaxUpload, MinTLSVersion, - Mirage, + ZonesSchemasMirage, NEL, - OpportunisticEncryption, + ZonesSchemasOpportunisticEncryption, OpportunisticOnion, OrangeToOrange, - OriginErrorPagePassThru, - Polish, + ZonesSchemasOriginErrorPagePassThru, + ZonesSchemasPolish, PrefetchPreload, ProxyReadTimeout, PseudoIPV4, ZonesReplaceInsecureJS, - ResponseBuffering, - RocketLoader, + ZonesSchemasResponseBuffering, + ZonesSchemasRocketLoader, ZonesSchemasAutomaticPlatformOptimization, SecurityHeaders, - SecurityLevel, - ServerSideExcludes, + ZonesSchemasSecurityLevel, + ZonesSchemasServerSideExclude, ZonesSha1Support, - SortQueryStringForCache, - SSL, + ZonesSchemasSortQueryStringForCache, + ZonesSchemasSSL, SSLRecommender, ZonesTLS1_2Only, TLS1_3, TLSClientAuth, - TrueClientIPHeader, - WAF, + ZonesSchemasTrueClientIPHeader, + ZonesSchemasWAF, WebP, Websocket, ] diff --git a/src/cloudflare/types/zones/setting_edit_response.py b/src/cloudflare/types/zones/setting_edit_response.py index 974838573d0..06b20495575 100644 --- a/src/cloudflare/types/zones/setting_edit_response.py +++ b/src/cloudflare/types/zones/setting_edit_response.py @@ -5,66 +5,180 @@ from typing_extensions import Literal, TypeAlias from .nel import NEL -from .ssl import SSL -from .waf import WAF from .ipv6 import IPV6 from .webp import WebP from .http2 import HTTP2 from .http3 import HTTP3 from .brotli import Brotli -from .mirage import Mirage -from .polish import Polish from .ciphers import Ciphers from .tls_1_3 import TLS1_3 from .zero_rtt import ZeroRTT from ..._models import BaseModel from .websocket import Websocket -from .cache_level import CacheLevel from .early_hints import EarlyHints from .pseudo_ipv4 import PseudoIPV4 from .advanced_ddos import AdvancedDDoS from .always_online import AlwaysOnline -from .browser_check import BrowserCheck from .challenge_ttl import ChallengeTTL -from .rocket_loader import RocketLoader from .image_resizing import ImageResizing -from .ip_geolocation import IPGeolocation -from .security_level import SecurityLevel from .min_tls_version import MinTLSVersion from .ssl_recommender import SSLRecommender from .tls_client_auth import TLSClientAuth -from .always_use_https import AlwaysUseHTTPS -from .development_mode import DevelopmentMode from .orange_to_orange import OrangeToOrange from .prefetch_preload import PrefetchPreload from .security_headers import SecurityHeaders -from .browser_cache_ttl import BrowserCacheTTL -from .email_obfuscation import EmailObfuscation from .h2_prioritization import H2Prioritization -from .hotlink_protection import HotlinkProtection from .proxy_read_timeout import ProxyReadTimeout -from .response_buffering import ResponseBuffering from .opportunistic_onion import OpportunisticOnion -from .server_side_excludes import ServerSideExcludes -from .true_client_ip_header import TrueClientIPHeader -from .automatic_https_rewrites import AutomaticHTTPSRewrites -from .opportunistic_encryption import OpportunisticEncryption -from .origin_error_page_pass_thru import OriginErrorPagePassThru -from .sort_query_string_for_cache import SortQueryStringForCache from .automatic_platform_optimization import AutomaticPlatformOptimization __all__ = [ "SettingEditResponse", + "ZonesSchemasAlwaysUseHTTPS", + "ZonesSchemasAutomaticHTTPSRewrites", + "ZonesSchemasBrowserCacheTTL", + "ZonesSchemasBrowserCheck", + "ZonesSchemasCacheLevel", "ZonesCNAMEFlattening", - "ZonesEdgeCacheTTL", + "ZonesSchemasDevelopmentMode", + "ZonesSchemasEdgeCacheTTL", + "ZonesSchemasEmailObfuscation", + "ZonesSchemasHotlinkProtection", + "ZonesSchemasIPGeolocation", "ZonesMaxUpload", + "ZonesSchemasMirage", + "ZonesSchemasOpportunisticEncryption", + "ZonesSchemasOriginErrorPagePassThru", + "ZonesSchemasPolish", "ZonesReplaceInsecureJS", + "ZonesSchemasResponseBuffering", + "ZonesSchemasRocketLoader", "ZonesSchemasAutomaticPlatformOptimization", + "ZonesSchemasSecurityLevel", + "ZonesSchemasServerSideExclude", "ZonesSha1Support", + "ZonesSchemasSortQueryStringForCache", + "ZonesSchemasSSL", "ZonesTLS1_2Only", + "ZonesSchemasTrueClientIPHeader", + "ZonesSchemasWAF", ] +class ZonesSchemasAlwaysUseHTTPS(BaseModel): + id: Literal["always_use_https"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasAutomaticHTTPSRewrites(BaseModel): + id: Literal["automatic_https_rewrites"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasBrowserCacheTTL(BaseModel): + id: Literal["browser_cache_ttl"] + """ID of the zone setting.""" + + value: Literal[ + 0, + 30, + 60, + 120, + 300, + 1200, + 1800, + 3600, + 7200, + 10800, + 14400, + 18000, + 28800, + 43200, + 57600, + 72000, + 86400, + 172800, + 259200, + 345600, + 432000, + 691200, + 1382400, + 2073600, + 2678400, + 5356800, + 16070400, + 31536000, + ] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasBrowserCheck(BaseModel): + id: Literal["browser_check"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasCacheLevel(BaseModel): + id: Literal["cache_level"] + """ID of the zone setting.""" + + value: Literal["aggressive", "basic", "simplified"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesCNAMEFlattening(BaseModel): id: Literal["cname_flattening"] """How to flatten the cname destination.""" @@ -82,7 +196,31 @@ class ZonesCNAMEFlattening(BaseModel): """last time this setting was modified.""" -class ZonesEdgeCacheTTL(BaseModel): +class ZonesSchemasDevelopmentMode(BaseModel): + id: Literal["development_mode"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + time_remaining: Optional[float] = None + """ + Value of the zone setting. Notes: The interval (in seconds) from when + development mode expires (positive integer) or last expired (negative integer) + for the domain. If development mode has never been enabled, this value is false. + """ + + +class ZonesSchemasEdgeCacheTTL(BaseModel): id: Literal["edge_cache_ttl"] """ID of the zone setting.""" @@ -121,6 +259,57 @@ class ZonesEdgeCacheTTL(BaseModel): """last time this setting was modified.""" +class ZonesSchemasEmailObfuscation(BaseModel): + id: Literal["email_obfuscation"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasHotlinkProtection(BaseModel): + id: Literal["hotlink_protection"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasIPGeolocation(BaseModel): + id: Literal["ip_geolocation"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesMaxUpload(BaseModel): id: Literal["max_upload"] """identifier of the zone setting.""" @@ -138,6 +327,74 @@ class ZonesMaxUpload(BaseModel): """last time this setting was modified.""" +class ZonesSchemasMirage(BaseModel): + id: Literal["mirage"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasOpportunisticEncryption(BaseModel): + id: Literal["opportunistic_encryption"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasOriginErrorPagePassThru(BaseModel): + id: Literal["origin_error_page_pass_thru"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasPolish(BaseModel): + id: Literal["polish"] + """ID of the zone setting.""" + + value: Literal["off", "lossless", "lossy"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesReplaceInsecureJS(BaseModel): id: Literal["replace_insecure_js"] """ID of the zone setting.""" @@ -155,6 +412,40 @@ class ZonesReplaceInsecureJS(BaseModel): """last time this setting was modified.""" +class ZonesSchemasResponseBuffering(BaseModel): + id: Literal["response_buffering"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasRocketLoader(BaseModel): + id: Literal["rocket_loader"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesSchemasAutomaticPlatformOptimization(BaseModel): id: Literal["automatic_platform_optimization"] """ID of the zone setting.""" @@ -172,6 +463,40 @@ class ZonesSchemasAutomaticPlatformOptimization(BaseModel): """last time this setting was modified.""" +class ZonesSchemasSecurityLevel(BaseModel): + id: Literal["security_level"] + """ID of the zone setting.""" + + value: Literal["off", "essentially_off", "low", "medium", "high", "under_attack"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasServerSideExclude(BaseModel): + id: Literal["server_side_exclude"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesSha1Support(BaseModel): id: Literal["sha1_support"] """Zone setting identifier.""" @@ -189,6 +514,40 @@ class ZonesSha1Support(BaseModel): """last time this setting was modified.""" +class ZonesSchemasSortQueryStringForCache(BaseModel): + id: Literal["sort_query_string_for_cache"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasSSL(BaseModel): + id: Literal["ssl"] + """ID of the zone setting.""" + + value: Literal["off", "flexible", "full", "strict"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesTLS1_2Only(BaseModel): id: Literal["tls_1_2_only"] """Zone setting identifier.""" @@ -206,58 +565,92 @@ class ZonesTLS1_2Only(BaseModel): """last time this setting was modified.""" +class ZonesSchemasTrueClientIPHeader(BaseModel): + id: Literal["true_client_ip_header"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasWAF(BaseModel): + id: Literal["waf"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + SettingEditResponse: TypeAlias = Union[ ZeroRTT, AdvancedDDoS, AlwaysOnline, - AlwaysUseHTTPS, - AutomaticHTTPSRewrites, + ZonesSchemasAlwaysUseHTTPS, + ZonesSchemasAutomaticHTTPSRewrites, Brotli, - BrowserCacheTTL, - BrowserCheck, - CacheLevel, + ZonesSchemasBrowserCacheTTL, + ZonesSchemasBrowserCheck, + ZonesSchemasCacheLevel, ChallengeTTL, Ciphers, ZonesCNAMEFlattening, - DevelopmentMode, + ZonesSchemasDevelopmentMode, EarlyHints, - ZonesEdgeCacheTTL, - EmailObfuscation, + ZonesSchemasEdgeCacheTTL, + ZonesSchemasEmailObfuscation, H2Prioritization, - HotlinkProtection, + ZonesSchemasHotlinkProtection, HTTP2, HTTP3, ImageResizing, - IPGeolocation, + ZonesSchemasIPGeolocation, IPV6, ZonesMaxUpload, MinTLSVersion, - Mirage, + ZonesSchemasMirage, NEL, - OpportunisticEncryption, + ZonesSchemasOpportunisticEncryption, OpportunisticOnion, OrangeToOrange, - OriginErrorPagePassThru, - Polish, + ZonesSchemasOriginErrorPagePassThru, + ZonesSchemasPolish, PrefetchPreload, ProxyReadTimeout, PseudoIPV4, ZonesReplaceInsecureJS, - ResponseBuffering, - RocketLoader, + ZonesSchemasResponseBuffering, + ZonesSchemasRocketLoader, ZonesSchemasAutomaticPlatformOptimization, SecurityHeaders, - SecurityLevel, - ServerSideExcludes, + ZonesSchemasSecurityLevel, + ZonesSchemasServerSideExclude, ZonesSha1Support, - SortQueryStringForCache, - SSL, + ZonesSchemasSortQueryStringForCache, + ZonesSchemasSSL, SSLRecommender, ZonesTLS1_2Only, TLS1_3, TLSClientAuth, - TrueClientIPHeader, - WAF, + ZonesSchemasTrueClientIPHeader, + ZonesSchemasWAF, WebP, Websocket, ] diff --git a/src/cloudflare/types/zones/setting_get_response.py b/src/cloudflare/types/zones/setting_get_response.py index f7550d15ce9..b6f4930c618 100644 --- a/src/cloudflare/types/zones/setting_get_response.py +++ b/src/cloudflare/types/zones/setting_get_response.py @@ -5,66 +5,180 @@ from typing_extensions import Literal, TypeAlias from .nel import NEL -from .ssl import SSL -from .waf import WAF from .ipv6 import IPV6 from .webp import WebP from .http2 import HTTP2 from .http3 import HTTP3 from .brotli import Brotli -from .mirage import Mirage -from .polish import Polish from .ciphers import Ciphers from .tls_1_3 import TLS1_3 from .zero_rtt import ZeroRTT from ..._models import BaseModel from .websocket import Websocket -from .cache_level import CacheLevel from .early_hints import EarlyHints from .pseudo_ipv4 import PseudoIPV4 from .advanced_ddos import AdvancedDDoS from .always_online import AlwaysOnline -from .browser_check import BrowserCheck from .challenge_ttl import ChallengeTTL -from .rocket_loader import RocketLoader from .image_resizing import ImageResizing -from .ip_geolocation import IPGeolocation -from .security_level import SecurityLevel from .min_tls_version import MinTLSVersion from .ssl_recommender import SSLRecommender from .tls_client_auth import TLSClientAuth -from .always_use_https import AlwaysUseHTTPS -from .development_mode import DevelopmentMode from .orange_to_orange import OrangeToOrange from .prefetch_preload import PrefetchPreload from .security_headers import SecurityHeaders -from .browser_cache_ttl import BrowserCacheTTL -from .email_obfuscation import EmailObfuscation from .h2_prioritization import H2Prioritization -from .hotlink_protection import HotlinkProtection from .proxy_read_timeout import ProxyReadTimeout -from .response_buffering import ResponseBuffering from .opportunistic_onion import OpportunisticOnion -from .server_side_excludes import ServerSideExcludes -from .true_client_ip_header import TrueClientIPHeader -from .automatic_https_rewrites import AutomaticHTTPSRewrites -from .opportunistic_encryption import OpportunisticEncryption -from .origin_error_page_pass_thru import OriginErrorPagePassThru -from .sort_query_string_for_cache import SortQueryStringForCache from .automatic_platform_optimization import AutomaticPlatformOptimization __all__ = [ "SettingGetResponse", + "ZonesSchemasAlwaysUseHTTPS", + "ZonesSchemasAutomaticHTTPSRewrites", + "ZonesSchemasBrowserCacheTTL", + "ZonesSchemasBrowserCheck", + "ZonesSchemasCacheLevel", "ZonesCNAMEFlattening", - "ZonesEdgeCacheTTL", + "ZonesSchemasDevelopmentMode", + "ZonesSchemasEdgeCacheTTL", + "ZonesSchemasEmailObfuscation", + "ZonesSchemasHotlinkProtection", + "ZonesSchemasIPGeolocation", "ZonesMaxUpload", + "ZonesSchemasMirage", + "ZonesSchemasOpportunisticEncryption", + "ZonesSchemasOriginErrorPagePassThru", + "ZonesSchemasPolish", "ZonesReplaceInsecureJS", + "ZonesSchemasResponseBuffering", + "ZonesSchemasRocketLoader", "ZonesSchemasAutomaticPlatformOptimization", + "ZonesSchemasSecurityLevel", + "ZonesSchemasServerSideExclude", "ZonesSha1Support", + "ZonesSchemasSortQueryStringForCache", + "ZonesSchemasSSL", "ZonesTLS1_2Only", + "ZonesSchemasTrueClientIPHeader", + "ZonesSchemasWAF", ] +class ZonesSchemasAlwaysUseHTTPS(BaseModel): + id: Literal["always_use_https"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasAutomaticHTTPSRewrites(BaseModel): + id: Literal["automatic_https_rewrites"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasBrowserCacheTTL(BaseModel): + id: Literal["browser_cache_ttl"] + """ID of the zone setting.""" + + value: Literal[ + 0, + 30, + 60, + 120, + 300, + 1200, + 1800, + 3600, + 7200, + 10800, + 14400, + 18000, + 28800, + 43200, + 57600, + 72000, + 86400, + 172800, + 259200, + 345600, + 432000, + 691200, + 1382400, + 2073600, + 2678400, + 5356800, + 16070400, + 31536000, + ] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasBrowserCheck(BaseModel): + id: Literal["browser_check"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasCacheLevel(BaseModel): + id: Literal["cache_level"] + """ID of the zone setting.""" + + value: Literal["aggressive", "basic", "simplified"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesCNAMEFlattening(BaseModel): id: Literal["cname_flattening"] """How to flatten the cname destination.""" @@ -82,7 +196,31 @@ class ZonesCNAMEFlattening(BaseModel): """last time this setting was modified.""" -class ZonesEdgeCacheTTL(BaseModel): +class ZonesSchemasDevelopmentMode(BaseModel): + id: Literal["development_mode"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + time_remaining: Optional[float] = None + """ + Value of the zone setting. Notes: The interval (in seconds) from when + development mode expires (positive integer) or last expired (negative integer) + for the domain. If development mode has never been enabled, this value is false. + """ + + +class ZonesSchemasEdgeCacheTTL(BaseModel): id: Literal["edge_cache_ttl"] """ID of the zone setting.""" @@ -121,6 +259,57 @@ class ZonesEdgeCacheTTL(BaseModel): """last time this setting was modified.""" +class ZonesSchemasEmailObfuscation(BaseModel): + id: Literal["email_obfuscation"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasHotlinkProtection(BaseModel): + id: Literal["hotlink_protection"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasIPGeolocation(BaseModel): + id: Literal["ip_geolocation"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesMaxUpload(BaseModel): id: Literal["max_upload"] """identifier of the zone setting.""" @@ -138,6 +327,74 @@ class ZonesMaxUpload(BaseModel): """last time this setting was modified.""" +class ZonesSchemasMirage(BaseModel): + id: Literal["mirage"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasOpportunisticEncryption(BaseModel): + id: Literal["opportunistic_encryption"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasOriginErrorPagePassThru(BaseModel): + id: Literal["origin_error_page_pass_thru"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasPolish(BaseModel): + id: Literal["polish"] + """ID of the zone setting.""" + + value: Literal["off", "lossless", "lossy"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesReplaceInsecureJS(BaseModel): id: Literal["replace_insecure_js"] """ID of the zone setting.""" @@ -155,6 +412,40 @@ class ZonesReplaceInsecureJS(BaseModel): """last time this setting was modified.""" +class ZonesSchemasResponseBuffering(BaseModel): + id: Literal["response_buffering"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasRocketLoader(BaseModel): + id: Literal["rocket_loader"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesSchemasAutomaticPlatformOptimization(BaseModel): id: Literal["automatic_platform_optimization"] """ID of the zone setting.""" @@ -172,6 +463,40 @@ class ZonesSchemasAutomaticPlatformOptimization(BaseModel): """last time this setting was modified.""" +class ZonesSchemasSecurityLevel(BaseModel): + id: Literal["security_level"] + """ID of the zone setting.""" + + value: Literal["off", "essentially_off", "low", "medium", "high", "under_attack"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasServerSideExclude(BaseModel): + id: Literal["server_side_exclude"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesSha1Support(BaseModel): id: Literal["sha1_support"] """Zone setting identifier.""" @@ -189,6 +514,40 @@ class ZonesSha1Support(BaseModel): """last time this setting was modified.""" +class ZonesSchemasSortQueryStringForCache(BaseModel): + id: Literal["sort_query_string_for_cache"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasSSL(BaseModel): + id: Literal["ssl"] + """ID of the zone setting.""" + + value: Literal["off", "flexible", "full", "strict"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesTLS1_2Only(BaseModel): id: Literal["tls_1_2_only"] """Zone setting identifier.""" @@ -206,58 +565,92 @@ class ZonesTLS1_2Only(BaseModel): """last time this setting was modified.""" +class ZonesSchemasTrueClientIPHeader(BaseModel): + id: Literal["true_client_ip_header"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + +class ZonesSchemasWAF(BaseModel): + id: Literal["waf"] + """ID of the zone setting.""" + + value: Literal["on", "off"] + """Current value of the zone setting.""" + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + SettingGetResponse: TypeAlias = Union[ ZeroRTT, AdvancedDDoS, AlwaysOnline, - AlwaysUseHTTPS, - AutomaticHTTPSRewrites, + ZonesSchemasAlwaysUseHTTPS, + ZonesSchemasAutomaticHTTPSRewrites, Brotli, - BrowserCacheTTL, - BrowserCheck, - CacheLevel, + ZonesSchemasBrowserCacheTTL, + ZonesSchemasBrowserCheck, + ZonesSchemasCacheLevel, ChallengeTTL, Ciphers, ZonesCNAMEFlattening, - DevelopmentMode, + ZonesSchemasDevelopmentMode, EarlyHints, - ZonesEdgeCacheTTL, - EmailObfuscation, + ZonesSchemasEdgeCacheTTL, + ZonesSchemasEmailObfuscation, H2Prioritization, - HotlinkProtection, + ZonesSchemasHotlinkProtection, HTTP2, HTTP3, ImageResizing, - IPGeolocation, + ZonesSchemasIPGeolocation, IPV6, ZonesMaxUpload, MinTLSVersion, - Mirage, + ZonesSchemasMirage, NEL, - OpportunisticEncryption, + ZonesSchemasOpportunisticEncryption, OpportunisticOnion, OrangeToOrange, - OriginErrorPagePassThru, - Polish, + ZonesSchemasOriginErrorPagePassThru, + ZonesSchemasPolish, PrefetchPreload, ProxyReadTimeout, PseudoIPV4, ZonesReplaceInsecureJS, - ResponseBuffering, - RocketLoader, + ZonesSchemasResponseBuffering, + ZonesSchemasRocketLoader, ZonesSchemasAutomaticPlatformOptimization, SecurityHeaders, - SecurityLevel, - ServerSideExcludes, + ZonesSchemasSecurityLevel, + ZonesSchemasServerSideExclude, ZonesSha1Support, - SortQueryStringForCache, - SSL, + ZonesSchemasSortQueryStringForCache, + ZonesSchemasSSL, SSLRecommender, ZonesTLS1_2Only, TLS1_3, TLSClientAuth, - TrueClientIPHeader, - WAF, + ZonesSchemasTrueClientIPHeader, + ZonesSchemasWAF, WebP, Websocket, ] diff --git a/src/cloudflare/types/zones/sort_query_string_for_cache.py b/src/cloudflare/types/zones/sort_query_string_for_cache.py index ca2fea8aaac..859d57fdc89 100644 --- a/src/cloudflare/types/zones/sort_query_string_for_cache.py +++ b/src/cloudflare/types/zones/sort_query_string_for_cache.py @@ -1,26 +1,23 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["SortQueryStringForCache"] +__all__ = ["SortQueryStringForCache", "Value"] -class SortQueryStringForCache(BaseModel): - id: Literal["sort_query_string_for_cache"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["on", "off"]] = None + """The status of Query String Sort""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). +class SortQueryStringForCache(BaseModel): + id: Optional[Literal["sort_query_string_for_cache"]] = None + """Turn on or off the reordering of query strings. + + When query strings have the same structure, caching improves. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/sort_query_string_for_cache_param.py b/src/cloudflare/types/zones/sort_query_string_for_cache_param.py new file mode 100644 index 00000000000..e859871e639 --- /dev/null +++ b/src/cloudflare/types/zones/sort_query_string_for_cache_param.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["SortQueryStringForCacheParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["on", "off"] + """The status of Query String Sort""" + + +class SortQueryStringForCacheParam(TypedDict, total=False): + id: Literal["sort_query_string_for_cache"] + """Turn on or off the reordering of query strings. + + When query strings have the same structure, caching improves. + """ + + value: Value diff --git a/src/cloudflare/types/zones/ssl.py b/src/cloudflare/types/zones/ssl.py index 720c4eaa01b..61fbed293d0 100644 --- a/src/cloudflare/types/zones/ssl.py +++ b/src/cloudflare/types/zones/ssl.py @@ -1,26 +1,23 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["SSL"] +__all__ = ["SSL", "Value"] -class SSL(BaseModel): - id: Literal["ssl"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["off", "flexible", "full", "strict", "origin_pull"]] = None + """The encryption mode that Cloudflare uses to connect to your origin server.""" - value: Literal["off", "flexible", "full", "strict"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None +class SSL(BaseModel): + id: Optional[Literal["ssl"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Control options for the SSL feature of the Edge Certificates tab in the + Cloudflare SSL/TLS app. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/ssl_param.py b/src/cloudflare/types/zones/ssl_param.py new file mode 100644 index 00000000000..41455617b98 --- /dev/null +++ b/src/cloudflare/types/zones/ssl_param.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["SSLParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["off", "flexible", "full", "strict", "origin_pull"] + """The encryption mode that Cloudflare uses to connect to your origin server.""" + + +class SSLParam(TypedDict, total=False): + id: Literal["ssl"] + """ + Control options for the SSL feature of the Edge Certificates tab in the + Cloudflare SSL/TLS app. + """ + + value: Value diff --git a/src/cloudflare/types/zones/true_client_ip_header.py b/src/cloudflare/types/zones/true_client_ip_header.py index c81c57535bf..203b23235c7 100644 --- a/src/cloudflare/types/zones/true_client_ip_header.py +++ b/src/cloudflare/types/zones/true_client_ip_header.py @@ -1,26 +1,20 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["TrueClientIPHeader"] +__all__ = ["TrueClientIPHeader", "Value"] -class TrueClientIPHeader(BaseModel): - id: Literal["true_client_ip_header"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["on", "off"]] = None + """The status of True Client IP Header.""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None - """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). - """ +class TrueClientIPHeader(BaseModel): + id: Optional[Literal["true_client_ip_header"]] = None + """Turn on or off the True-Client-IP Header feature of the Cloudflare Network app.""" - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/true_client_ip_header_param.py b/src/cloudflare/types/zones/true_client_ip_header_param.py new file mode 100644 index 00000000000..e7508a5b53a --- /dev/null +++ b/src/cloudflare/types/zones/true_client_ip_header_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["TrueClientIPHeaderParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["on", "off"] + """The status of True Client IP Header.""" + + +class TrueClientIPHeaderParam(TypedDict, total=False): + id: Literal["true_client_ip_header"] + """Turn on or off the True-Client-IP Header feature of the Cloudflare Network app.""" + + value: Value diff --git a/src/cloudflare/types/zones/waf.py b/src/cloudflare/types/zones/waf.py index d5f4c0d363d..898cbdfee90 100644 --- a/src/cloudflare/types/zones/waf.py +++ b/src/cloudflare/types/zones/waf.py @@ -1,26 +1,24 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["WAF"] +__all__ = ["WAF", "Value"] -class WAF(BaseModel): - id: Literal["waf"] - """ID of the zone setting.""" +class Value(BaseModel): + value: Optional[Literal["on", "off"]] = None + """The status of WAF managed rules (previous version).""" - value: Literal["on", "off"] - """Current value of the zone setting.""" - editable: Optional[Literal[True, False]] = None +class WAF(BaseModel): + id: Optional[Literal["waf"]] = None """ - Whether or not this setting can be modified for this zone (based on your - Cloudflare plan level). + Turn on or off + [WAF managed rules (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/). + You cannot enable or disable individual WAF managed rules via Page Rules. """ - modified_on: Optional[datetime] = None - """last time this setting was modified.""" + value: Optional[Value] = None diff --git a/src/cloudflare/types/zones/waf_param.py b/src/cloudflare/types/zones/waf_param.py new file mode 100644 index 00000000000..8cefb453562 --- /dev/null +++ b/src/cloudflare/types/zones/waf_param.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["WAFParam", "Value"] + + +class Value(TypedDict, total=False): + value: Literal["on", "off"] + """The status of WAF managed rules (previous version).""" + + +class WAFParam(TypedDict, total=False): + id: Literal["waf"] + """ + Turn on or off + [WAF managed rules (previous version, deprecated)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/). + You cannot enable or disable individual WAF managed rules via Page Rules. + """ + + value: Value diff --git a/tests/api_resources/firewall/test_access_rules.py b/tests/api_resources/firewall/test_access_rules.py index f7b7debb11d..0e1faa1b86e 100644 --- a/tests/api_resources/firewall/test_access_rules.py +++ b/tests/api_resources/firewall/test_access_rules.py @@ -3,14 +3,20 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray -from cloudflare.types.firewall import AccessRuleCreateResponse +from cloudflare.types.firewall import ( + AccessRuleGetResponse, + AccessRuleEditResponse, + AccessRuleListResponse, + AccessRuleCreateResponse, + AccessRuleDeleteResponse, +) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -95,7 +101,7 @@ def test_method_list(self, client: Cloudflare) -> None: access_rule = client.firewall.access_rules.list( account_id="account_id", ) - assert_matches_type(SyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(SyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -114,7 +120,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: page=1, per_page=20, ) - assert_matches_type(SyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(SyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -126,7 +132,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_rule = response.parse() - assert_matches_type(SyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(SyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -138,7 +144,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_rule = response.parse() - assert_matches_type(SyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(SyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) assert cast(Any, response.is_closed) is True @@ -155,6 +161,225 @@ def test_path_params_list(self, client: Cloudflare) -> None: account_id="account_id", ) + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + access_rule = client.firewall.access_rules.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_delete_with_all_params(self, client: Cloudflare) -> None: + access_rule = client.firewall.access_rules.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.firewall.access_rules.with_raw_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_rule = response.parse() + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.firewall.access_rules.with_streaming_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_rule = response.parse() + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.firewall.access_rules.with_raw_response.delete( + rule_id="", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.firewall.access_rules.with_raw_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.access_rules.with_raw_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + access_rule = client.firewall.access_rules.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_edit_with_all_params(self, client: Cloudflare) -> None: + access_rule = client.firewall.access_rules.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={ + "target": "ip", + "value": "198.51.100.4", + }, + mode="block", + account_id="account_id", + notes="This rule is enabled because of an event that occurred on date X.", + ) + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_edit(self, client: Cloudflare) -> None: + response = client.firewall.access_rules.with_raw_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_rule = response.parse() + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_edit(self, client: Cloudflare) -> None: + with client.firewall.access_rules.with_streaming_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_rule = response.parse() + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_edit(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.firewall.access_rules.with_raw_response.edit( + rule_id="", + configuration={}, + mode="block", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.firewall.access_rules.with_raw_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.access_rules.with_raw_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + access_rule = client.firewall.access_rules.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_get_with_all_params(self, client: Cloudflare) -> None: + access_rule = client.firewall.access_rules.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.firewall.access_rules.with_raw_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_rule = response.parse() + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.firewall.access_rules.with_streaming_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_rule = response.parse() + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.firewall.access_rules.with_raw_response.get( + rule_id="", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.firewall.access_rules.with_raw_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.access_rules.with_raw_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + class TestAsyncAccessRules: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @@ -236,7 +461,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: access_rule = await async_client.firewall.access_rules.list( account_id="account_id", ) - assert_matches_type(AsyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(AsyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -255,7 +480,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) page=1, per_page=20, ) - assert_matches_type(AsyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(AsyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -267,7 +492,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_rule = await response.parse() - assert_matches_type(AsyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(AsyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -279,7 +504,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" access_rule = await response.parse() - assert_matches_type(AsyncV4PagePaginationArray[object], access_rule, path=["response"]) + assert_matches_type(AsyncV4PagePaginationArray[AccessRuleListResponse], access_rule, path=["response"]) assert cast(Any, response.is_closed) is True @@ -295,3 +520,222 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.firewall.access_rules.with_raw_response.list( account_id="account_id", ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + access_rule = await async_client.firewall.access_rules.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_delete_with_all_params(self, async_client: AsyncCloudflare) -> None: + access_rule = await async_client.firewall.access_rules.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.access_rules.with_raw_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_rule = await response.parse() + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.access_rules.with_streaming_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_rule = await response.parse() + assert_matches_type(Optional[AccessRuleDeleteResponse], access_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.delete( + rule_id="", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.delete( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + access_rule = await async_client.firewall.access_rules.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: + access_rule = await async_client.firewall.access_rules.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={ + "target": "ip", + "value": "198.51.100.4", + }, + mode="block", + account_id="account_id", + notes="This rule is enabled because of an event that occurred on date X.", + ) + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.access_rules.with_raw_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_rule = await response.parse() + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.access_rules.with_streaming_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_rule = await response.parse() + assert_matches_type(AccessRuleEditResponse, access_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.edit( + rule_id="", + configuration={}, + mode="block", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.edit( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + access_rule = await async_client.firewall.access_rules.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: + access_rule = await async_client.firewall.access_rules.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.access_rules.with_raw_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_rule = await response.parse() + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.access_rules.with_streaming_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_rule = await response.parse() + assert_matches_type(AccessRuleGetResponse, access_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.get( + rule_id="", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.access_rules.with_raw_response.get( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="account_id", + ) diff --git a/tests/api_resources/firewall/test_lockdowns.py b/tests/api_resources/firewall/test_lockdowns.py new file mode 100644 index 00000000000..b417a768998 --- /dev/null +++ b/tests/api_resources/firewall/test_lockdowns.py @@ -0,0 +1,555 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.firewall import ( + Lockdown, + LockdownDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestLockdowns: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + lockdown = client.firewall.lockdowns.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.firewall.lockdowns.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.firewall.lockdowns.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.lockdowns.with_raw_response.create( + zone_id="", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + lockdown = client.firewall.lockdowns.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.firewall.lockdowns.with_raw_response.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.firewall.lockdowns.with_streaming_response.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.lockdowns.with_raw_response.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `lock_downs_id` but received ''"): + client.firewall.lockdowns.with_raw_response.update( + lock_downs_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + lockdown = client.firewall.lockdowns.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + lockdown = client.firewall.lockdowns.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + created_on=parse_datetime("2014-01-01T05:20:00.12345Z"), + description="endpoints", + description_search="endpoints", + ip="1.2.3.4", + ip_range_search="1.2.3.0/16", + ip_search="1.2.3.4", + modified_on=parse_datetime("2014-01-01T05:20:00.12345Z"), + page=1, + per_page=1, + priority=5, + uri_search="/some/path", + ) + assert_matches_type(SyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.firewall.lockdowns.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = response.parse() + assert_matches_type(SyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.firewall.lockdowns.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = response.parse() + assert_matches_type(SyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.lockdowns.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + lockdown = client.firewall.lockdowns.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[LockdownDeleteResponse], lockdown, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.firewall.lockdowns.with_raw_response.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = response.parse() + assert_matches_type(Optional[LockdownDeleteResponse], lockdown, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.firewall.lockdowns.with_streaming_response.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = response.parse() + assert_matches_type(Optional[LockdownDeleteResponse], lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.lockdowns.with_raw_response.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `lock_downs_id` but received ''"): + client.firewall.lockdowns.with_raw_response.delete( + lock_downs_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + lockdown = client.firewall.lockdowns.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.firewall.lockdowns.with_raw_response.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.firewall.lockdowns.with_streaming_response.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.lockdowns.with_raw_response.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `lock_downs_id` but received ''"): + client.firewall.lockdowns.with_raw_response.get( + lock_downs_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncLockdowns: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + lockdown = await async_client.firewall.lockdowns.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.lockdowns.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = await response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.lockdowns.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = await response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.create( + zone_id="", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + lockdown = await async_client.firewall.lockdowns.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.lockdowns.with_raw_response.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = await response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.lockdowns.with_streaming_response.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = await response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.update( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `lock_downs_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.update( + lock_downs_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configurations=[{}], + urls=["shop.example.com/*"], + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + lockdown = await async_client.firewall.lockdowns.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + lockdown = await async_client.firewall.lockdowns.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + created_on=parse_datetime("2014-01-01T05:20:00.12345Z"), + description="endpoints", + description_search="endpoints", + ip="1.2.3.4", + ip_range_search="1.2.3.0/16", + ip_search="1.2.3.4", + modified_on=parse_datetime("2014-01-01T05:20:00.12345Z"), + page=1, + per_page=1, + priority=5, + uri_search="/some/path", + ) + assert_matches_type(AsyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.lockdowns.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.lockdowns.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[Lockdown], lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + lockdown = await async_client.firewall.lockdowns.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[LockdownDeleteResponse], lockdown, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.lockdowns.with_raw_response.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = await response.parse() + assert_matches_type(Optional[LockdownDeleteResponse], lockdown, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.lockdowns.with_streaming_response.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = await response.parse() + assert_matches_type(Optional[LockdownDeleteResponse], lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.delete( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `lock_downs_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.delete( + lock_downs_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + lockdown = await async_client.firewall.lockdowns.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.lockdowns.with_raw_response.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + lockdown = await response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.lockdowns.with_streaming_response.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + lockdown = await response.parse() + assert_matches_type(Lockdown, lockdown, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.get( + lock_downs_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `lock_downs_id` but received ''"): + await async_client.firewall.lockdowns.with_raw_response.get( + lock_downs_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/firewall/test_rules.py b/tests/api_resources/firewall/test_rules.py new file mode 100644 index 00000000000..62388686851 --- /dev/null +++ b/tests/api_resources/firewall/test_rules.py @@ -0,0 +1,1112 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.firewall import ( + FirewallRule, + RuleEditResponse, + RuleCreateResponse, + RuleBulkEditResponse, + RuleBulkDeleteResponse, + RuleBulkUpdateResponse, +) + +# pyright: reportDeprecated=false + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRules: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + filter={ + "description": "Restrict access from these browsers on this address range.", + "expression": '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + "paused": False, + "ref": "FIL-100", + }, + ) + + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.create( + zone_id="", + action={}, + filter={}, + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + filter={ + "description": "Restrict access from these browsers on this address range.", + "expression": '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + "paused": False, + "ref": "FIL-100", + }, + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + action={}, + filter={}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.firewall.rules.with_raw_response.update( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(SyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="372e67954025e0ba6aaa6d586b9e0b60", + action="block", + description="mir", + page=1, + paused=False, + per_page=5, + ) + + assert_matches_type(SyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(SyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(SyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.firewall.rules.with_raw_response.delete( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[RuleBulkDeleteResponse], rule, path=["response"]) + + @parametrize + def test_raw_response_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(Optional[RuleBulkDeleteResponse], rule, path=["response"]) + + @parametrize + def test_streaming_response_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(Optional[RuleBulkDeleteResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.bulk_delete( + zone_id="", + ) + + @parametrize + def test_method_bulk_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.bulk_edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"]) + + @parametrize + def test_raw_response_bulk_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.bulk_edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"]) + + @parametrize + def test_streaming_response_bulk_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.bulk_edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_bulk_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.bulk_edit( + zone_id="", + body={}, + ) + + @parametrize + def test_method_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert_matches_type(Optional[RuleBulkUpdateResponse], rule, path=["response"]) + + @parametrize + def test_raw_response_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(Optional[RuleBulkUpdateResponse], rule, path=["response"]) + + @parametrize + def test_streaming_response_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(Optional[RuleBulkUpdateResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.bulk_update( + zone_id="", + body={}, + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[RuleEditResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(Optional[RuleEditResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(Optional[RuleEditResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.firewall.rules.with_raw_response.edit( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + def test_method_get_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = client.firewall.rules.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="372e67954025e0ba6aaa6d586b9e0b60", + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.firewall.rules.with_raw_response.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.firewall.rules.with_streaming_response.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.rules.with_raw_response.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.firewall.rules.with_raw_response.get( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncRules: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + filter={ + "description": "Restrict access from these browsers on this address range.", + "expression": '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + "paused": False, + "ref": "FIL-100", + }, + ) + + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.create( + zone_id="", + action={}, + filter={}, + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + filter={ + "description": "Restrict access from these browsers on this address range.", + "expression": '(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + "paused": False, + "ref": "FIL-100", + }, + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.update( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + action={}, + filter={}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.firewall.rules.with_raw_response.update( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + filter={}, + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(AsyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="372e67954025e0ba6aaa6d586b9e0b60", + action="block", + description="mir", + page=1, + paused=False, + per_page=5, + ) + + assert_matches_type(AsyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[FirewallRule], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.delete( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.firewall.rules.with_raw_response.delete( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[RuleBulkDeleteResponse], rule, path=["response"]) + + @parametrize + async def test_raw_response_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(Optional[RuleBulkDeleteResponse], rule, path=["response"]) + + @parametrize + async def test_streaming_response_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(Optional[RuleBulkDeleteResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.bulk_delete( + zone_id="", + ) + + @parametrize + async def test_method_bulk_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.bulk_edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"]) + + @parametrize + async def test_raw_response_bulk_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.bulk_edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"]) + + @parametrize + async def test_streaming_response_bulk_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.bulk_edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_bulk_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.bulk_edit( + zone_id="", + body={}, + ) + + @parametrize + async def test_method_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert_matches_type(Optional[RuleBulkUpdateResponse], rule, path=["response"]) + + @parametrize + async def test_raw_response_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(Optional[RuleBulkUpdateResponse], rule, path=["response"]) + + @parametrize + async def test_streaming_response_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(Optional[RuleBulkUpdateResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.bulk_update( + zone_id="", + body={}, + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[RuleEditResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(Optional[RuleEditResponse], rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(Optional[RuleEditResponse], rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.edit( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.firewall.rules.with_raw_response.edit( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rule = await async_client.firewall.rules.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="372e67954025e0ba6aaa6d586b9e0b60", + ) + + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.firewall.rules.with_raw_response.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.firewall.rules.with_streaming_response.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(FirewallRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.rules.with_raw_response.get( + rule_id="372e67954025e0ba6aaa6d586b9e0b60", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.firewall.rules.with_raw_response.get( + rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/firewall/test_ua_rules.py b/tests/api_resources/firewall/test_ua_rules.py new file mode 100644 index 00000000000..4dae57f296b --- /dev/null +++ b/tests/api_resources/firewall/test_ua_rules.py @@ -0,0 +1,599 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.firewall import ( + UARuleGetResponse, + UARuleListResponse, + UARuleCreateResponse, + UARuleDeleteResponse, + UARuleUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestUARules: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={ + "target": "ip", + "value": "198.51.100.4", + }, + mode="block", + ) + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.firewall.ua_rules.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = response.parse() + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.firewall.ua_rules.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = response.parse() + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.ua_rules.with_raw_response.create( + zone_id="", + configuration={}, + mode="block", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={ + "target": "ip", + "value": "198.51.100.4", + }, + mode="block", + ) + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.firewall.ua_rules.with_raw_response.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = response.parse() + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.firewall.ua_rules.with_streaming_response.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = response.parse() + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.ua_rules.with_raw_response.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + configuration={}, + mode="block", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `ua_rule_id` but received ''"): + client.firewall.ua_rules.with_raw_response.update( + ua_rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + description="abusive", + description_search="abusive", + page=1, + per_page=1, + ua_search="Safari", + ) + assert_matches_type(SyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.firewall.ua_rules.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = response.parse() + assert_matches_type(SyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.firewall.ua_rules.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = response.parse() + assert_matches_type(SyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.ua_rules.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(UARuleDeleteResponse, ua_rule, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.firewall.ua_rules.with_raw_response.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = response.parse() + assert_matches_type(UARuleDeleteResponse, ua_rule, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.firewall.ua_rules.with_streaming_response.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = response.parse() + assert_matches_type(UARuleDeleteResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.ua_rules.with_raw_response.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `ua_rule_id` but received ''"): + client.firewall.ua_rules.with_raw_response.delete( + ua_rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + ua_rule = client.firewall.ua_rules.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(UARuleGetResponse, ua_rule, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.firewall.ua_rules.with_raw_response.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = response.parse() + assert_matches_type(UARuleGetResponse, ua_rule, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.firewall.ua_rules.with_streaming_response.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = response.parse() + assert_matches_type(UARuleGetResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.ua_rules.with_raw_response.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `ua_rule_id` but received ''"): + client.firewall.ua_rules.with_raw_response.get( + ua_rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncUARules: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={ + "target": "ip", + "value": "198.51.100.4", + }, + mode="block", + ) + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.ua_rules.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = await response.parse() + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.ua_rules.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = await response.parse() + assert_matches_type(UARuleCreateResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.create( + zone_id="", + configuration={}, + mode="block", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={ + "target": "ip", + "value": "198.51.100.4", + }, + mode="block", + ) + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.ua_rules.with_raw_response.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = await response.parse() + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.ua_rules.with_streaming_response.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = await response.parse() + assert_matches_type(UARuleUpdateResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.update( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + configuration={}, + mode="block", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `ua_rule_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.update( + ua_rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + configuration={}, + mode="block", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + description="abusive", + description_search="abusive", + page=1, + per_page=1, + ua_search="Safari", + ) + assert_matches_type(AsyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.ua_rules.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.ua_rules.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[UARuleListResponse], ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(UARuleDeleteResponse, ua_rule, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.ua_rules.with_raw_response.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = await response.parse() + assert_matches_type(UARuleDeleteResponse, ua_rule, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.ua_rules.with_streaming_response.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = await response.parse() + assert_matches_type(UARuleDeleteResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.delete( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `ua_rule_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.delete( + ua_rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + ua_rule = await async_client.firewall.ua_rules.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(UARuleGetResponse, ua_rule, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.ua_rules.with_raw_response.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ua_rule = await response.parse() + assert_matches_type(UARuleGetResponse, ua_rule, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.ua_rules.with_streaming_response.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ua_rule = await response.parse() + assert_matches_type(UARuleGetResponse, ua_rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.get( + ua_rule_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `ua_rule_id` but received ''"): + await async_client.firewall.ua_rules.with_raw_response.get( + ua_rule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/firewall/waf/test_overrides.py b/tests/api_resources/firewall/waf/test_overrides.py new file mode 100644 index 00000000000..8fe442652cd --- /dev/null +++ b/tests/api_resources/firewall/waf/test_overrides.py @@ -0,0 +1,586 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.firewall.waf import ( + Override, + OverrideDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestOverrides: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + override = client.firewall.waf.overrides.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + urls=["shop.example.com/*"], + ) + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.firewall.waf.overrides.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = response.parse() + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.firewall.waf.overrides.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = response.parse() + assert_matches_type(Override, override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.create( + zone_id="", + urls=["shop.example.com/*"], + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + override = client.firewall.waf.overrides.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + override = client.firewall.waf.overrides.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={ + "block": "challenge", + "challenge": "challenge", + "default": "challenge", + "disable": "challenge", + "simulate": "challenge", + }, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.firewall.waf.overrides.with_raw_response.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = response.parse() + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.firewall.waf.overrides.with_streaming_response.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = response.parse() + assert_matches_type(Override, override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `overrides_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.update( + overrides_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + override = client.firewall.waf.overrides.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[Override], override, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + override = client.firewall.waf.overrides.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + page=1, + per_page=5, + ) + assert_matches_type(SyncV4PagePaginationArray[Override], override, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.firewall.waf.overrides.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = response.parse() + assert_matches_type(SyncV4PagePaginationArray[Override], override, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.firewall.waf.overrides.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = response.parse() + assert_matches_type(SyncV4PagePaginationArray[Override], override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + override = client.firewall.waf.overrides.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[OverrideDeleteResponse], override, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.firewall.waf.overrides.with_raw_response.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = response.parse() + assert_matches_type(Optional[OverrideDeleteResponse], override, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.firewall.waf.overrides.with_streaming_response.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = response.parse() + assert_matches_type(Optional[OverrideDeleteResponse], override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `overrides_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.delete( + overrides_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + override = client.firewall.waf.overrides.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Override, override, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.firewall.waf.overrides.with_raw_response.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = response.parse() + assert_matches_type(Override, override, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.firewall.waf.overrides.with_streaming_response.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = response.parse() + assert_matches_type(Override, override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `overrides_id` but received ''"): + client.firewall.waf.overrides.with_raw_response.get( + overrides_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncOverrides: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + override = await async_client.firewall.waf.overrides.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + urls=["shop.example.com/*"], + ) + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.waf.overrides.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = await response.parse() + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.waf.overrides.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = await response.parse() + assert_matches_type(Override, override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.create( + zone_id="", + urls=["shop.example.com/*"], + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + override = await async_client.firewall.waf.overrides.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + override = await async_client.firewall.waf.overrides.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={ + "block": "challenge", + "challenge": "challenge", + "default": "challenge", + "disable": "challenge", + "simulate": "challenge", + }, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.waf.overrides.with_raw_response.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = await response.parse() + assert_matches_type(Override, override, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.waf.overrides.with_streaming_response.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = await response.parse() + assert_matches_type(Override, override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.update( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `overrides_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.update( + overrides_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="023e105f4ecef8ad9ca31a8372d0c353", + rewrite_action={}, + rules={"100015": "challenge"}, + urls=["shop.example.com/*"], + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + override = await async_client.firewall.waf.overrides.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[Override], override, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + override = await async_client.firewall.waf.overrides.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + page=1, + per_page=5, + ) + assert_matches_type(AsyncV4PagePaginationArray[Override], override, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.waf.overrides.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[Override], override, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.waf.overrides.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[Override], override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + override = await async_client.firewall.waf.overrides.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[OverrideDeleteResponse], override, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.waf.overrides.with_raw_response.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = await response.parse() + assert_matches_type(Optional[OverrideDeleteResponse], override, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.waf.overrides.with_streaming_response.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = await response.parse() + assert_matches_type(Optional[OverrideDeleteResponse], override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.delete( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `overrides_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.delete( + overrides_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + override = await async_client.firewall.waf.overrides.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Override, override, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.waf.overrides.with_raw_response.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + override = await response.parse() + assert_matches_type(Override, override, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.waf.overrides.with_streaming_response.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + override = await response.parse() + assert_matches_type(Override, override, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.get( + overrides_id="de677e5818985db1285d0e80225f06e5", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `overrides_id` but received ''"): + await async_client.firewall.waf.overrides.with_raw_response.get( + overrides_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/firewall/waf/test_packages.py b/tests/api_resources/firewall/waf/test_packages.py new file mode 100644 index 00000000000..f6f0d2b054e --- /dev/null +++ b/tests/api_resources/firewall/waf/test_packages.py @@ -0,0 +1,231 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.firewall.waf import PackageGetResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestPackages: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + package = client.firewall.waf.packages.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[object], package, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + package = client.firewall.waf.packages.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + direction="asc", + match="any", + name="USER", + order="name", + page=1, + per_page=5, + ) + assert_matches_type(SyncV4PagePaginationArray[object], package, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.firewall.waf.packages.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = response.parse() + assert_matches_type(SyncV4PagePaginationArray[object], package, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.firewall.waf.packages.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = response.parse() + assert_matches_type(SyncV4PagePaginationArray[object], package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.waf.packages.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + package = client.firewall.waf.packages.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(PackageGetResponse, package, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.firewall.waf.packages.with_raw_response.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = response.parse() + assert_matches_type(PackageGetResponse, package, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.firewall.waf.packages.with_streaming_response.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = response.parse() + assert_matches_type(PackageGetResponse, package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.firewall.waf.packages.with_raw_response.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_id` but received ''"): + client.firewall.waf.packages.with_raw_response.get( + package_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncPackages: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + package = await async_client.firewall.waf.packages.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[object], package, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + package = await async_client.firewall.waf.packages.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + direction="asc", + match="any", + name="USER", + order="name", + page=1, + per_page=5, + ) + assert_matches_type(AsyncV4PagePaginationArray[object], package, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.waf.packages.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[object], package, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.waf.packages.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[object], package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.waf.packages.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + package = await async_client.firewall.waf.packages.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(PackageGetResponse, package, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.firewall.waf.packages.with_raw_response.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = await response.parse() + assert_matches_type(PackageGetResponse, package, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.firewall.waf.packages.with_streaming_response.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = await response.parse() + assert_matches_type(PackageGetResponse, package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.firewall.waf.packages.with_raw_response.get( + package_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_id` but received ''"): + await async_client.firewall.waf.packages.with_raw_response.get( + package_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/pagerules/__init__.py b/tests/api_resources/pagerules/__init__.py deleted file mode 100644 index fd8019a9a1a..00000000000 --- a/tests/api_resources/pagerules/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/pagerules/test_settings.py b/tests/api_resources/pagerules/test_settings.py deleted file mode 100644 index 06b7aa3a064..00000000000 --- a/tests/api_resources/pagerules/test_settings.py +++ /dev/null @@ -1,98 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, Optional, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.types.pagerules import SettingListResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestSettings: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - setting = client.pagerules.settings.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(Optional[SettingListResponse], setting, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.pagerules.settings.with_raw_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - setting = response.parse() - assert_matches_type(Optional[SettingListResponse], setting, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.pagerules.settings.with_streaming_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - setting = response.parse() - assert_matches_type(Optional[SettingListResponse], setting, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.pagerules.settings.with_raw_response.list( - zone_id="", - ) - - -class TestAsyncSettings: - parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - setting = await async_client.pagerules.settings.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(Optional[SettingListResponse], setting, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.pagerules.settings.with_raw_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - setting = await response.parse() - assert_matches_type(Optional[SettingListResponse], setting, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.pagerules.settings.with_streaming_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - setting = await response.parse() - assert_matches_type(Optional[SettingListResponse], setting, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.pagerules.settings.with_raw_response.list( - zone_id="", - ) diff --git a/tests/api_resources/test_filters.py b/tests/api_resources/test_filters.py new file mode 100644 index 00000000000..eb126fb8162 --- /dev/null +++ b/tests/api_resources/test_filters.py @@ -0,0 +1,758 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.filters import ( + FirewallFilter, + FilterCreateResponse, + FilterBulkDeleteResponse, + FilterBulkUpdateResponse, +) + +# pyright: reportDeprecated=false + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestFilters: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) + + assert_matches_type(Optional[FilterCreateResponse], filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.filters.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = response.parse() + assert_matches_type(Optional[FilterCreateResponse], filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.filters.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = response.parse() + assert_matches_type(Optional[FilterCreateResponse], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.filters.with_raw_response.create( + zone_id="", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.filters.with_raw_response.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.filters.with_streaming_response.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.filters.with_raw_response.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="", + body={}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `filter_id` but received ''"): + client.filters.with_raw_response.update( + filter_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(SyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="372e67954025e0ba6aaa6d586b9e0b61", + description="browsers", + expression="php", + page=1, + paused=False, + per_page=5, + ref="FIL-100", + ) + + assert_matches_type(SyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.filters.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = response.parse() + assert_matches_type(SyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.filters.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = response.parse() + assert_matches_type(SyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.filters.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.filters.with_raw_response.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.filters.with_streaming_response.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.filters.with_raw_response.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `filter_id` but received ''"): + client.filters.with_raw_response.delete( + filter_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[FilterBulkDeleteResponse], filter, path=["response"]) + + @parametrize + def test_raw_response_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.filters.with_raw_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = response.parse() + assert_matches_type(Optional[FilterBulkDeleteResponse], filter, path=["response"]) + + @parametrize + def test_streaming_response_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.filters.with_streaming_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = response.parse() + assert_matches_type(Optional[FilterBulkDeleteResponse], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_bulk_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.filters.with_raw_response.bulk_delete( + zone_id="", + ) + + @parametrize + def test_method_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[FilterBulkUpdateResponse], filter, path=["response"]) + + @parametrize + def test_raw_response_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.filters.with_raw_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = response.parse() + assert_matches_type(Optional[FilterBulkUpdateResponse], filter, path=["response"]) + + @parametrize + def test_streaming_response_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.filters.with_streaming_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = response.parse() + assert_matches_type(Optional[FilterBulkUpdateResponse], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_bulk_update(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.filters.with_raw_response.bulk_update( + zone_id="", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = client.filters.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.filters.with_raw_response.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.filters.with_streaming_response.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.filters.with_raw_response.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `filter_id` but received ''"): + client.filters.with_raw_response.get( + filter_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncFilters: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) + + assert_matches_type(Optional[FilterCreateResponse], filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.filters.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = await response.parse() + assert_matches_type(Optional[FilterCreateResponse], filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.filters.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = await response.parse() + assert_matches_type(Optional[FilterCreateResponse], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.filters.with_raw_response.create( + zone_id="", + expression='(http.request.uri.path ~ ".*wp-login.php" or http.request.uri.path ~ ".*xmlrpc.php") and ip.addr ne 172.16.22.155', + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.filters.with_raw_response.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = await response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.filters.with_streaming_response.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = await response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.filters.with_raw_response.update( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="", + body={}, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `filter_id` but received ''"): + await async_client.filters.with_raw_response.update( + filter_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + body={}, + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(AsyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="372e67954025e0ba6aaa6d586b9e0b61", + description="browsers", + expression="php", + page=1, + paused=False, + per_page=5, + ref="FIL-100", + ) + + assert_matches_type(AsyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.filters.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.filters.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[FirewallFilter], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.filters.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.filters.with_raw_response.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = await response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.filters.with_streaming_response.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = await response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.filters.with_raw_response.delete( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `filter_id` but received ''"): + await async_client.filters.with_raw_response.delete( + filter_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[FilterBulkDeleteResponse], filter, path=["response"]) + + @parametrize + async def test_raw_response_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.filters.with_raw_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = await response.parse() + assert_matches_type(Optional[FilterBulkDeleteResponse], filter, path=["response"]) + + @parametrize + async def test_streaming_response_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.filters.with_streaming_response.bulk_delete( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = await response.parse() + assert_matches_type(Optional[FilterBulkDeleteResponse], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_bulk_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.filters.with_raw_response.bulk_delete( + zone_id="", + ) + + @parametrize + async def test_method_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(Optional[FilterBulkUpdateResponse], filter, path=["response"]) + + @parametrize + async def test_raw_response_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.filters.with_raw_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = await response.parse() + assert_matches_type(Optional[FilterBulkUpdateResponse], filter, path=["response"]) + + @parametrize + async def test_streaming_response_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.filters.with_streaming_response.bulk_update( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = await response.parse() + assert_matches_type(Optional[FilterBulkUpdateResponse], filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_bulk_update(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.filters.with_raw_response.bulk_update( + zone_id="", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + filter = await async_client.filters.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.filters.with_raw_response.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + filter = await response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.filters.with_streaming_response.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + filter = await response.parse() + assert_matches_type(FirewallFilter, filter, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.filters.with_raw_response.get( + filter_id="372e67954025e0ba6aaa6d586b9e0b61", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `filter_id` but received ''"): + await async_client.filters.with_raw_response.get( + filter_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/test_pagerules.py b/tests/api_resources/test_pagerules.py index 7759cea316d..68a6822ba59 100644 --- a/tests/api_resources/test_pagerules.py +++ b/tests/api_resources/test_pagerules.py @@ -15,8 +15,6 @@ PageruleDeleteResponse, ) -# pyright: reportDeprecated=false - base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -25,68 +23,60 @@ class TestPagerules: @parametrize def test_method_create(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - + pagerule = client.pagerules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[ - { - "id": "forwarding_url", - "value": { - "status_code": 301, - "url": "http://www.example.com/somewhere/$1/astring/$2/anotherstring/$3", - }, - } - ], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - priority=0, - status="active", - ) - + pagerule = client.pagerules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[ + { + "id": "browser_check", + "value": "on", + } + ], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + priority=0, + status="active", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.pagerules.with_raw_response.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) + response = client.pagerules.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -95,52 +85,32 @@ def test_raw_response_create(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.pagerules.with_streaming_response.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - pagerule = response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + with client.pagerules.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + pagerule = response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_create(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.pagerules.with_raw_response.create( - zone_id="", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - - @parametrize - def test_method_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.pagerules.with_raw_response.create( + zone_id="", actions=[{}], targets=[ { @@ -153,44 +123,101 @@ def test_method_update(self, client: Cloudflare) -> None: ], ) + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + pagerule = client.pagerules.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize def test_method_update_with_all_params(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[ - { - "id": "forwarding_url", - "value": { - "status_code": 301, - "url": "http://www.example.com/somewhere/$1/astring/$2/anotherstring/$3", - }, - } - ], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - priority=0, - status="active", - ) - + pagerule = client.pagerules.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[ + { + "id": "browser_check", + "value": "on", + } + ], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + priority=0, + status="active", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize def test_raw_response_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.pagerules.with_raw_response.update( + response = client.pagerules.with_raw_response.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + pagerule = response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.pagerules.with_streaming_response.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + pagerule = response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.pagerules.with_raw_response.update( pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", actions=[{}], targets=[ { @@ -203,16 +230,9 @@ def test_raw_response_update(self, client: Cloudflare) -> None: ], ) - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) - - @parametrize - def test_streaming_response_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.pagerules.with_streaming_response.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + client.pagerules.with_raw_response.update( + pagerule_id="", zone_id="023e105f4ecef8ad9ca31a8372d0c353", actions=[{}], targets=[ @@ -224,78 +244,31 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: "target": "url", } ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - pagerule = response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.pagerules.with_raw_response.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - client.pagerules.with_raw_response.update( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) + ) @parametrize def test_method_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - + pagerule = client.pagerules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - direction="asc", - match="any", - order="status", - status="active", - ) - + pagerule = client.pagerules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + direction="asc", + match="any", + order="status", + status="active", + ) assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.pagerules.with_raw_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = client.pagerules.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -304,43 +277,38 @@ def test_raw_response_list(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.pagerules.with_streaming_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with client.pagerules.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = response.parse() - assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) + pagerule = response.parse() + assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.pagerules.with_raw_response.list( - zone_id="", - ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.pagerules.with_raw_response.list( + zone_id="", + ) @parametrize def test_method_delete(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - + pagerule = client.pagerules.delete( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageruleDeleteResponse], pagerule, path=["response"]) @parametrize def test_raw_response_delete(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.pagerules.with_raw_response.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = client.pagerules.with_raw_response.delete( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -349,81 +317,71 @@ def test_raw_response_delete(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_delete(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.pagerules.with_streaming_response.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with client.pagerules.with_streaming_response.delete( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = response.parse() - assert_matches_type(Optional[PageruleDeleteResponse], pagerule, path=["response"]) + pagerule = response.parse() + assert_matches_type(Optional[PageruleDeleteResponse], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_delete(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.pagerules.with_raw_response.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - client.pagerules.with_raw_response.delete( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - @parametrize - def test_method_edit(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.edit( + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.pagerules.with_raw_response.delete( pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + client.pagerules.with_raw_response.delete( + pagerule_id="", zone_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + pagerule = client.pagerules.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize def test_method_edit_with_all_params(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[ - { - "id": "forwarding_url", - "value": { - "status_code": 301, - "url": "http://www.example.com/somewhere/$1/astring/$2/anotherstring/$3", - }, - } - ], - priority=0, - status="active", - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - + pagerule = client.pagerules.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[ + { + "id": "browser_check", + "value": "on", + } + ], + priority=0, + status="active", + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize def test_raw_response_edit(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.pagerules.with_raw_response.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = client.pagerules.with_raw_response.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -432,51 +390,46 @@ def test_raw_response_edit(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_edit(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.pagerules.with_streaming_response.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with client.pagerules.with_streaming_response.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + pagerule = response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_edit(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.pagerules.with_raw_response.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - client.pagerules.with_raw_response.edit( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = client.pagerules.get( + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.pagerules.with_raw_response.edit( pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + client.pagerules.with_raw_response.edit( + pagerule_id="", zone_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + pagerule = client.pagerules.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.pagerules.with_raw_response.get( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = client.pagerules.with_raw_response.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -485,33 +438,31 @@ def test_raw_response_get(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.pagerules.with_streaming_response.get( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with client.pagerules.with_streaming_response.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + pagerule = response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.pagerules.with_raw_response.get( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.pagerules.with_raw_response.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - client.pagerules.with_raw_response.get( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + client.pagerules.with_raw_response.get( + pagerule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) class TestAsyncPagerules: @@ -519,68 +470,60 @@ class TestAsyncPagerules: @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - + pagerule = await async_client.pagerules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[ - { - "id": "forwarding_url", - "value": { - "status_code": 301, - "url": "http://www.example.com/somewhere/$1/astring/$2/anotherstring/$3", - }, - } - ], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - priority=0, - status="active", - ) - + pagerule = await async_client.pagerules.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[ + { + "id": "browser_check", + "value": "on", + } + ], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + priority=0, + status="active", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.pagerules.with_raw_response.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) + response = await async_client.pagerules.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -589,52 +532,32 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.pagerules.with_streaming_response.create( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - pagerule = await response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + async with async_client.pagerules.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + pagerule = await response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.pagerules.with_raw_response.create( - zone_id="", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - - @parametrize - async def test_method_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.pagerules.with_raw_response.create( + zone_id="", actions=[{}], targets=[ { @@ -647,44 +570,101 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: ], ) + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + pagerule = await async_client.pagerules.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[ - { - "id": "forwarding_url", - "value": { - "status_code": 301, - "url": "http://www.example.com/somewhere/$1/astring/$2/anotherstring/$3", - }, - } - ], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - priority=0, - status="active", - ) - + pagerule = await async_client.pagerules.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[ + { + "id": "browser_check", + "value": "on", + } + ], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + priority=0, + status="active", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.pagerules.with_raw_response.update( + response = await async_client.pagerules.with_raw_response.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + pagerule = await response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.pagerules.with_streaming_response.update( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[{}], + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + pagerule = await response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.pagerules.with_raw_response.update( pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", actions=[{}], targets=[ { @@ -697,16 +677,9 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: ], ) - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = await response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) - - @parametrize - async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.pagerules.with_streaming_response.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + await async_client.pagerules.with_raw_response.update( + pagerule_id="", zone_id="023e105f4ecef8ad9ca31a8372d0c353", actions=[{}], targets=[ @@ -718,78 +691,31 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> "target": "url", } ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - pagerule = await response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.pagerules.with_raw_response.update( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - await async_client.pagerules.with_raw_response.update( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[{}], - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) + ) @parametrize async def test_method_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - + pagerule = await async_client.pagerules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - direction="asc", - match="any", - order="status", - status="active", - ) - + pagerule = await async_client.pagerules.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + direction="asc", + match="any", + order="status", + status="active", + ) assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.pagerules.with_raw_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = await async_client.pagerules.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -798,43 +724,38 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.pagerules.with_streaming_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + async with async_client.pagerules.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = await response.parse() - assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) + pagerule = await response.parse() + assert_matches_type(Optional[PageruleListResponse], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.pagerules.with_raw_response.list( - zone_id="", - ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.pagerules.with_raw_response.list( + zone_id="", + ) @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - + pagerule = await async_client.pagerules.delete( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageruleDeleteResponse], pagerule, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.pagerules.with_raw_response.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = await async_client.pagerules.with_raw_response.delete( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -843,81 +764,71 @@ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.pagerules.with_streaming_response.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + async with async_client.pagerules.with_streaming_response.delete( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = await response.parse() - assert_matches_type(Optional[PageruleDeleteResponse], pagerule, path=["response"]) + pagerule = await response.parse() + assert_matches_type(Optional[PageruleDeleteResponse], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.pagerules.with_raw_response.delete( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - await async_client.pagerules.with_raw_response.delete( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - @parametrize - async def test_method_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.edit( + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.pagerules.with_raw_response.delete( pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + await async_client.pagerules.with_raw_response.delete( + pagerule_id="", zone_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + pagerule = await async_client.pagerules.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - actions=[ - { - "id": "forwarding_url", - "value": { - "status_code": 301, - "url": "http://www.example.com/somewhere/$1/astring/$2/anotherstring/$3", - }, - } - ], - priority=0, - status="active", - targets=[ - { - "constraint": { - "operator": "matches", - "value": "*example.com/images/*", - }, - "target": "url", - } - ], - ) - + pagerule = await async_client.pagerules.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + actions=[ + { + "id": "browser_check", + "value": "on", + } + ], + priority=0, + status="active", + targets=[ + { + "constraint": { + "operator": "matches", + "value": "*example.com/images/*", + }, + "target": "url", + } + ], + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.pagerules.with_raw_response.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = await async_client.pagerules.with_raw_response.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -926,51 +837,46 @@ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.pagerules.with_streaming_response.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + async with async_client.pagerules.with_streaming_response.edit( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = await response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + pagerule = await response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.pagerules.with_raw_response.edit( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - await async_client.pagerules.with_raw_response.edit( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - pagerule = await async_client.pagerules.get( + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.pagerules.with_raw_response.edit( pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + await async_client.pagerules.with_raw_response.edit( + pagerule_id="", zone_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + pagerule = await async_client.pagerules.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert_matches_type(Optional[PageRule], pagerule, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.pagerules.with_raw_response.get( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + response = await async_client.pagerules.with_raw_response.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -979,30 +885,28 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.pagerules.with_streaming_response.get( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + async with async_client.pagerules.with_streaming_response.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pagerule = await response.parse() - assert_matches_type(Optional[PageRule], pagerule, path=["response"]) + pagerule = await response.parse() + assert_matches_type(Optional[PageRule], pagerule, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.pagerules.with_raw_response.get( - pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", - zone_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): - await async_client.pagerules.with_raw_response.get( - pagerule_id="", - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.pagerules.with_raw_response.get( + pagerule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `pagerule_id` but received ''"): + await async_client.pagerules.with_raw_response.get( + pagerule_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/test_rate_limits.py b/tests/api_resources/test_rate_limits.py new file mode 100644 index 00000000000..5c9ce8627d8 --- /dev/null +++ b/tests/api_resources/test_rate_limits.py @@ -0,0 +1,770 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.rate_limits import ( + RateLimit, + RateLimitDeleteResponse, +) + +# pyright: reportDeprecated=false + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRateLimits: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + match={ + "headers": [ + { + "name": "Cf-Cache-Status", + "op": "eq", + "value": "HIT", + } + ], + "request": { + "methods": ["GET", "POST"], + "schemes": ["HTTP", "HTTPS"], + "url": "*.example.org/path*", + }, + "response": {"origin_traffic": True}, + }, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.rate_limits.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.rate_limits.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.rate_limits.with_raw_response.create( + zone_id="", + action={}, + match={}, + period=900, + threshold=60, + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(SyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + page=1, + per_page=1, + ) + + assert_matches_type(SyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.rate_limits.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = response.parse() + assert_matches_type(SyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.rate_limits.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = response.parse() + assert_matches_type(SyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.rate_limits.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(RateLimitDeleteResponse, rate_limit, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.rate_limits.with_raw_response.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = response.parse() + assert_matches_type(RateLimitDeleteResponse, rate_limit, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.rate_limits.with_streaming_response.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = response.parse() + assert_matches_type(RateLimitDeleteResponse, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.rate_limits.with_raw_response.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rate_limit_id` but received ''"): + client.rate_limits.with_raw_response.delete( + rate_limit_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_edit_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + match={ + "headers": [ + { + "name": "Cf-Cache-Status", + "op": "eq", + "value": "HIT", + } + ], + "request": { + "methods": ["GET", "POST"], + "schemes": ["HTTP", "HTTPS"], + "url": "*.example.org/path*", + }, + "response": {"origin_traffic": True}, + }, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.rate_limits.with_raw_response.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.rate_limits.with_streaming_response.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_edit(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.rate_limits.with_raw_response.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + action={}, + match={}, + period=900, + threshold=60, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rate_limit_id` but received ''"): + client.rate_limits.with_raw_response.edit( + rate_limit_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = client.rate_limits.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = client.rate_limits.with_raw_response.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with client.rate_limits.with_streaming_response.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.rate_limits.with_raw_response.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rate_limit_id` but received ''"): + client.rate_limits.with_raw_response.get( + rate_limit_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncRateLimits: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + match={ + "headers": [ + { + "name": "Cf-Cache-Status", + "op": "eq", + "value": "HIT", + } + ], + "request": { + "methods": ["GET", "POST"], + "schemes": ["HTTP", "HTTPS"], + "url": "*.example.org/path*", + }, + "response": {"origin_traffic": True}, + }, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.rate_limits.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = await response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.rate_limits.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = await response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.rate_limits.with_raw_response.create( + zone_id="", + action={}, + match={}, + period=900, + threshold=60, + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(AsyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + page=1, + per_page=1, + ) + + assert_matches_type(AsyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.rate_limits.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.rate_limits.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[RateLimit], rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.rate_limits.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(RateLimitDeleteResponse, rate_limit, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.rate_limits.with_raw_response.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = await response.parse() + assert_matches_type(RateLimitDeleteResponse, rate_limit, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.rate_limits.with_streaming_response.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = await response.parse() + assert_matches_type(RateLimitDeleteResponse, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.rate_limits.with_raw_response.delete( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rate_limit_id` but received ''"): + await async_client.rate_limits.with_raw_response.delete( + rate_limit_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={ + "mode": "simulate", + "response": { + "body": "This request has been rate-limited.", + "content_type": "text/xml", + }, + "timeout": 86400, + }, + match={ + "headers": [ + { + "name": "Cf-Cache-Status", + "op": "eq", + "value": "HIT", + } + ], + "request": { + "methods": ["GET", "POST"], + "schemes": ["HTTP", "HTTPS"], + "url": "*.example.org/path*", + }, + "response": {"origin_traffic": True}, + }, + period=900, + threshold=60, + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.rate_limits.with_raw_response.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = await response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.rate_limits.with_streaming_response.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = await response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.rate_limits.with_raw_response.edit( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + action={}, + match={}, + period=900, + threshold=60, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rate_limit_id` but received ''"): + await async_client.rate_limits.with_raw_response.edit( + rate_limit_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + action={}, + match={}, + period=900, + threshold=60, + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + rate_limit = await async_client.rate_limits.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + response = await async_client.rate_limits.with_raw_response.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rate_limit = await response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + async with async_client.rate_limits.with_streaming_response.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rate_limit = await response.parse() + assert_matches_type(RateLimit, rate_limit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.rate_limits.with_raw_response.get( + rate_limit_id="372e67954025e0ba6aaa6d586b9e0b59", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rate_limit_id` but received ''"): + await async_client.rate_limits.with_raw_response.get( + rate_limit_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + )