cf_rules module
- class cf_rules.Cloudflare(folder: str | None = None)[source]
- __init__(folder: str | None = None)[source]
Initialize Cloudflare class
Specify a folder argument where expressions will be saved
>>> cf = Cloudflare("my_expressions")
- auth_key(email: str, key: str) dict [source]
Get your global API Key through cloudflare profile (API Keys section)
- Raises:
Error – Email or key is not provided
Warning
This will grant all domains access to this API library, prefer using
auth_token()
https://dash.cloudflare.com/profile/api-tokens
email -> Email account
key -> Global API Key
>>> cf.auth_key("cloudflare@example.com", "your-global-api-key") >>> {"success": True, "result": {"id": "a1b2c3", "email": "cloudflare@example.com", ...}} # OR >>> {"success": False, "errors": [{"code": 6003, "message": "Invalid request headers", ...}]}
- auth_token(bearer_token: str) dict [source]
Generate a specific token through cloudflare profile (API Tokens section)
- Raises:
Error – Bearer token is not provided
Note
This will grant only specific domains/permissions related access to this API library
https://dash.cloudflare.com/profile/api-tokens
bearer_token -> API Token
>>> cf.auth_token("your-specific-bearer-token") >>> {"success": True, "result": {"id": "a1b2c3", "status": "active"}, ...} # OR >>> {"success": False, "errors": [{"code": 1000, "message": "Invalid API token"}], ...}
- get_domains() dict [source]
Get all domains
- Raises:
Error – If not authenticated (use
auth_key(email, key)
orauth_token(bearer_token)
)
>>> cf.get_domains() >>> {"count": 2, "domains": ["example.com", "example.fr"], "result": [{"id": "a1b2c3", "name": "example.com", ...}, ...]}
- property domains: list[DomainObject]
Get all domains as a list of
DomainObject
Access any value of the object with the dot operator
Better handling compared to
get_domains()
, return directly the result key of the function>>> cf.domains >>> [{"id": "a1b2c3", "name": "example.com", ...}, {"id": "d4e5f6", "name": "example.fr", ...}]
- get_domain(domain_name: str) DomainObject [source]
Get a specific domain as
DomainObject
- Raises:
Error – If not authenticated (use
auth_key(email, key)
orauth_token(bearer_token)
)Error – If domain is not found (list all domains using cf.domains)
Important
This function is the “core” for all other functions, it is needed for every other function to work
>>> cf.get_domain("example.com") >>> {"id": "a1b2c3", "name": "example.com", ...} >>> domain = cf.get_domain("example.fr") >>> domain.name # OR domain["name"] >>> "example.fr"
- set_plan(domain_name: str)[source]
Save current website plan
Note
Will define the current plan of the website in the instance of the class
>>> cf.set_plan("example.com") # Now the maximum available rules for this domain depends on the current plan
- get_rulesets(domain_name: str) dict [source]
Get all rulesets from a specific domain
>>> cf.get_rulesets("example.com") >>> {"count": 4, "rulesets": ["default", "Cloudflare Normalization Ruleset", ...], "result": [{"id": "a1b2c3", "name": "default", ...}]}
- rulesets(domain_name: str) list[RulesetObject] [source]
Get all rulesets as a list of
RulesetObject
Access any value of the object with the dot operator
Better handling compared to
get_rulesets()
, return directly the result key of the function>>> cf.rulesets >>> [{"id": "a1b2c3", "name": "default", ...}, {"id": "d4e5f6", "name": "Cloudflare Normalization Ruleset", ...}]
- get_custom_ruleset(domain_name: str) RulesetObject [source]
Get the custom ruleset from a specific domain as
RulesetObject
It should be the only ruleset with the source “firewall_custom” as per Cloudflare’s documentation. This is the ruleset where all custom rules are stored.
- Raises:
Error – If no custom ruleset is found
>>> cf.get_custom_ruleset("example.com") >>> {"id": "a1b2c3", "name": "default", "source": "firewall_custom", ...}
- get_rules(domain_name: str) dict [source]
Get all rules from a specific domain
- Raises:
Error – If no rules are found
>>> cf.get_rules("example.com") >>> {"count": 3, "rules": ["Bad Bots", "Bad IP", "Bad AS"], "result": [{"id": "a1b2c3", "description": "Bad Bots", ...}, ...]}
- rules(domain_name: str) list[RuleObject] [source]
Get all rules as a list of
RuleObject
Access any value of the object with the dot operator
Better handling compared to
get_rules()
, return directly the result key of the function>>> cf.rules >>> [{"id": "a1b2c3", "description": "Bad Bots", ...}, {"id": "d4e5f6", "description": "Bad IP", ...}, ...]
- get_rule(domain_name: str, *, rule_name: str | None = None, rule_id: str | None = None) RuleObject [source]
Get a specific rule by name or ID from a specific domain as
RuleObject
- Raises:
>>> cf.get_rule("example.com", rule_name="Bad Bots") >>> {"id": "a1b2c3", "enabled": True, "action": "block", "description": "Bad Bots", "expression": "(http.user_agent contains "DotBot")", ...}
- export_rules(domain_name: str) True [source]
Export all expressions from a specific domain
Note
Will save all expressions into multiple files in the folder specified in Cloudflare’s constructor
>>> cf.export_rules("example.com") # "Bad Bots.txt", "Bad IP.txt", "Bad AS.txt" files created in "my_expressions" folder
- export_rule(domain_name: str, *, rule_name: str | None = None, rule_id: str | None = None) True [source]
Export the expression of a rule in a txt file
- Raises:
Error – Rule name or rule ID is not provided
Note
Will save the expression into a file in the folder specified in Cloudflare’s constructor
>>> cf.export_rule("example.com", "Bad Bots") # "Bad Bots.txt" file created in "my_expressions" folder
- create_rule(domain_name: str, rule_file: str, rule_name: str | None = None, action: str | None = None) bool [source]
Create a rule with a specific expression
action -> Please refer to https://developers.cloudflare.com/ruleset-engine/rules-language/actions/
Available actions as string: managed_challenge, js_challenge, challenge, block, skip, log
Action is read from the header of the file by default, but you can specify it manually. Else it will be “managed_challenge”
- Raises:
>>> cf.create_rule("example.com", "Bad URL.txt", action="managed_challenge") # Create a rule with the expression in "Bad URL.txt" and override the action to "managed_challenge" >>> cf.create_rule("example.com", "Bad IP.txt", "Not allowed IP") # Create a rule named "Not allowed IP" with the expression in "Bad IP.txt" with the action in the header of the file
- update_rule(domain_name: str, rule_file: str, rule_name: str | None = None, action: str | None = None) bool [source]
Update a rule with a specific expression
- Raises:
Error – Rule file is not found
Todo
First modify “Bad Bots.txt” by changing the expression or adding a new rule
>>> cf.update_rule("example.com", "Bad Bots.txt") # Will update the remote rule "Bad Bots" with the expression in "Bad Bots.txt" >>> cf.update_rule("example.com", "Bad IP.txt", "Not allowed IP", "block") # Will update the remote rule "Not allowed IP" with the expression in "Bad IP.txt" and override the action to "block"
- delete_rule(domain_name: str, rule_name: str) bool [source]
Delete a rule from a specific domain
>>> cf.delete_rule("example.com", "Bad AS") # Will delete the rule "Bad AS" remotely from the domain "example.com"
- purge_rules(domain_name: str) bool [source]
Purge all rules from a specific domain
>>> cf.purge_rules("example.com") # Will delete all rules remotely from the domain "example.com"
- import_rules(domain_name: str, actions_all: str | None = None) bool [source]
Import all expressions from all txt file
actions_all -> Set the same action for all imported rules, please refer to https://developers.cloudflare.com/ruleset-engine/rules-language/actions/
Available actions as string: managed_challenge, js_challenge, challenge, block, skip, log
- Raises:
Error – Cannot create more rules (5 used / 5 available depending on the current plan)
Note
If you have a better plan, please register your plan using the method
set_plan(domain_name)
>>> cf.import_rules("example.com") # Will use the action in the header specific for every file >>> cf.import_rules("example.com", "block") # Will import all rules and use the "block" action
- import_rule(domain_name: str, rule_file: str, rule_name: str | None = None, action: str | None = None) bool
Import a rule with a specific expression
Alias for
create_rule()
>>> cf.import_rule("example.com", "Bad URL.txt", action="managed_challenge") # Import a rule with the expression in "Bad URL.txt", will use the action in the header if specified or force it using the action argument
- class cf_rules.Utils(directory: str = None)[source]
- __init__(directory: str = None) None [source]
Utils class to manage Cloudflare data
>>> utils = Utils("my_expressions")
- change_directory(directory: str) None [source]
Change the directory where the expressions are stored
>>> utils.change_directory("my_expressions2")
- static escape(string) str [source]
Escape a string
Simply replace slashes with underscores for the file name
>>> utils.escape("Test/1") >>> "Test_1"
- static unescape(string: str) str [source]
Unescape a string
Simply replace underscores with slashes for the rule name
>>> utils.unescape("Test_1") >>> "Test/1"
- static beautify(expression: str) str [source]
Beautify a Cloudflare expression
>>> utils.beautify("(cf.client.bot) or (cf.threat_score ge 1)") # (cf.client.bot) or # (cf.threat_score ge 1)
- write_expression(rule_file: str, rule_expression: str, header: dict | None = None) None [source]
Write an expression to a readable text file
>>> utils.write_expression("IsBot", "(cf.client.bot)") >>> utils.write_expression("IsBot", "(cf.client.bot)", header={"action": "managed_challenge", "enabled": "True"})
- read_expression(rule_file: str) tuple[str, str] [source]
Read an expression from a file
>>> utils.read_expression("IsBot") >>> "(cf.client.bot)"
- process_header(header_line: str) dict | None [source]
Process the header of an expression file if it exists It retrieves all header data and returns a dictionary
>>> utils.process_header("#! action:block enabled:True !#") >>> {"action": "block", "enabled": "True"}
- static get_json_key(json: dict, keys: list[str | int]) object [source]
Get an element from a json using a list of keys
>>> utils.get_json_key({"a": {"b": {"c": "d"}}}, ["a", "b", "c"]) >>> "d" >>> utils.get_json_key({"a": ["b", "c"]}, ["a", 1]) >>> "c"
- exception cf_rules.Error(message: str | None = None)[source]
- __init__(message: str | None = None) Error [source]
Error class to handle Cloudflare errors
>>> error = Error() # OR >>> error = Error("This is an error message")
- handle(request_json: dict, keys: list[str | int]) any [source]
Handle errors from a request response
- Raises:
Error – If auth error
>>> error.handle({"success": True, "result": {"a": "b"}}, ["success"]) >>> True
>>> error.handle({"success": False, "errors": [{"code": "invalid_parameter", "message": "Invalid parameter"}]}, ["success"]) >>> False
>>> error.handle({"success": False, "errors": [{"code": 9109, "message": "Invalid access token"}], "messages": [], "result": None}, ["errors"][0]["message"]) >>> "Invalid access token"