cloudflare / python-cloudflare Goto Github PK
View Code? Open in Web Editor NEWThis project forked from cloudflare-api/python-cloudflare-v4
Python wrapper for the Cloudflare Client API v4
License: MIT License
This project forked from cloudflare-api/python-cloudflare-v4
Python wrapper for the Cloudflare Client API v4
License: MIT License
The PATCH method is currently not supported on this endpoint.
It would be very handy to turn on and off the 'Proxied' status of a DNS record.
Add a method which returns the total number of requests that the site has received.
Hi guys,
Thanks for the excellent API work, love it so far.
I've been trying to create firewall rules using:
`` def ban_ip_for_zone_id(self, ip, zone_id):
rule = {'mode': 'block', 'configuration': {'target': 'ip', 'value': ip},
'notes': 'Automatic block placed via Python script for IP : ' + str(ip)}
print(json.dumps(rule))
self.cf.zones.firewall.access_rules.rules.post(zone_id, data=json.dumps(rule))
without a lot of success. I keep getting this error:
CloudFlare.exceptions.CloudFlareAPIError: firewallaccessrules.api.bad_json
The JSON I get back to send in is:
{"notes": "Automatic block placed via Python script for IP : 103.89.91.156", "configuration": {"target": "ip", "value": "103.89.91.156"}, "mode": "block"}
I already JSON linted this thing. Am I missing something on the data structure? Your input is appreciated.
Hello!
I found a question in use, hoping to help me to answer it.
When I called the query firewall interface, I found that I could only get 25 pieces of information at a time.
How can I get all the information at once?
######################################################
def main():
cf = CloudFlare.CloudFlare(email= email,token=token)
zones = cf.zones.firewall.access_rules.rules(Zone_ID)
print(len(zones['result_info']))
######################################################
My e-mail address is yuan.22811422.com
Thank you and your team for contributing such practical code!
A beginner's respect!
Before inserting block rule to user/firewall/access_rules/rules
I trying to find IP, if it is already blocked:
result = cf.user.firewall.access_rules.rules.get(data={'configuration': { 'target': 'ip', 'value': bad_guy_ip }})
but I get exception:
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/CloudFlare/cloudflare.py", line 618, in get
params, data)
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/CloudFlare/cloudflare.py", line 75, in call_with_auth
params, data, files)
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/CloudFlare/cloudflare.py", line 424, in _call
params, data, files)
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/CloudFlare/cloudflare.py", line 319, in _raw
params, data, files)
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/CloudFlare/cloudflare.py", line 143, in _network
raise CloudFlareAPIError(0, 'You must specify identifier1')
CloudFlare.exceptions.CloudFlareAPIError: You must specify identifier1
so how to specify it, and why I need to do it in user-level, this rules are 'global'?
Hello,
I am using Cloudflare's Python library to make some API calls. The following call generates API error every time:
cf.zones.firewall.waf.packages.rules.patch(ZoneID,RulesetID,RuleID, params={"mode":"off"})
The error is
File "/usr/lib/python2.7/site-packages/CloudFlare/cloudflare.py", line 625, in patch
params, data)
File "/usr/lib/python2.7/site-packages/CloudFlare/cloudflare.py", line 75, in call_with_auth
params, data, files)
File "/usr/lib/python2.7/site-packages/CloudFlare/cloudflare.py", line 467, in _call
raise CloudFlareAPIError(code, message, error_chain)
CloudFlare.exceptions.CloudFlareAPIError: Invalid or missing WAF Rule mode
Everything is fine when submitting this call using curl as described here:
https://api.cloudflare.com/#waf-rules-edit-rule
Here's the code I'm using:
import CloudFlare
priv_key = "xxxx"
email = "xxxxx"
source = "xxxxx" # source zone id
target = "xxxxx" # target zone id
owasp = "xxx" # OWASP ruleset id
def replicate_rules():
cf = CloudFlare.CloudFlare(email=email, token=priv_key, raw=True)
for i in range (1,26):
rules = cf.zones.firewall.waf.packages.rules(source,owasp, params={"per_page":100, "page":i})
for x in rules["result"]:
cf.zones.firewall.waf.packages.rules.patch(target,owasp,x["id"], params={"mode":"x['mode']"})
Works fine with the following curls:
curl -H "X-Auth-User-Service-Key: $CF_API_CERTKEY" "https://api.cloudflare.com/client/v4/certificates?zone_id=[ZONE_ID]"
curl -H "X-Auth-User-Service-Key: $CF_API_CERTKEY" "https://api.cloudflare.com/client/v4/certificates/[CERT_ID]
Am trying to call with cf.certificates.get(zone_id). User error or bug?
I can successfully change other similar zone settings, like "automatic_https_rewrites", and it works perfectly, however when I try to change "always_use_https" I receive this error:
Traceback (most recent call last): File "/home/gonguinguen/medios/gluon/restricted.py", line 227, in restricted exec ccode in environment File "/home/gonguinguen/medios/applications/webmedios/controllers/admin.py", line 598, in <module> File "/home/gonguinguen/medios/gluon/globals.py", line 393, in <lambda> self._caller = lambda f: f() File "/home/gonguinguen/medios/applications/webmedios/controllers/admin.py", line 593, in test cf.zones.settings.always_use_https.patch(zone_id, data={"value": "on"}) AttributeError: '_add_with_auth' object has no attribute 'always_use_https'
Notice the call I use is the same for both settings, as told by the official Cloudflare documentation. But the error happens only with "always_use_https".
I tried doing my self the call using python requests.
import requests
result = requests.patch('https://api.cloudflare.com/client/v4/zones/%s/settings/always_use_https' %
zone_id,
data={'value': 'off'},
headers={
"Content-Type": "application/json",
"X-Auth-Key": cloudflare_user_api_key,
"X-Auth-Email": cloudflare_email
}
)
But this returns the error code 6007 with the message "Malformed JSON in request body"
I've contacted Cloudflare support, and they told me that the call is right.
Is this a bug in python-cloudflare library? Could it be related to requests module?
UPDATE
I've tried directly using the curl command and it works ok, so it isn't a bug in the Cloudflare API. Also, I've tried with several different zones, and the problem remains.
Hello.
Could you please help me?
How I can change settings for waf rules via cli4?
For example I need to change
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$zone_id/firewall/waf/packages/1e334934fd7ae32ad705667f8c1057aa/rules/100047WP" -H "Content-Type:application/json" -H "X-Auth-Key:$token" -H "X-Auth-Email:$login" --data '{"mode":"challenge"}'
Via cli4 it doesn't work :(
cli4 --patch mode=challenge /zones/:example.com/firewall/waf/packages/:1e334934fd7ae32ad705667f8c1057aa/rules/100047WP
Thank you for your work.
If you call cli4 like so:
python -m cli4 --put name=$record type=A ttl=120 content=$ip /zones/:$domain/dns_records/:$record
you will get the following error:
cli4: /zones/:<ZONE_NAME>/dns_records/:<RECORD> - 1004 DNS Validation Error
Without the TTL Attribute this works fine and returns the Expected Record in JSON Format.
Currently when using CloudFlare.CloudFlare.zones.dns_records.post()
including the argument proxied
as docuemnted by the API returns post() got an unexpected keyword argument 'proxied'
So we can create an API object that authenticates using the email / API key combo or using an API token. That the token
parameter to the initializer is overloaded for the two different uses (whether or not email
is also specified is what decides which it is) is already a bit questionable IMHO, but ok, I can live with that.
But check this out: if you happen to have the CF_API_EMAIL
environment variable defined then it will always interpret the token
parameter as an API key not an API token... but it will apparently try to use it, even if the CF_API_KEY
env var is also set. Or perhaps it stuffs all of the above into the headers. The result is that one gets "6003 Invalid request headers - api call failed" which isn't much of a clue to what's going on. Either there should be a more specific error, or it should just use the env vars, ignore the token
param, and issue a warning.
API Tokens in beta are more secure than API Keys because they can be limited to a specific domain. See:
Trying to check and configure logpush jobs and was hoping to use cli4 to do it quickly, but it doesn't know the logpush endpoint. It just returns the error /zones/:zoneid/logpush - not found. Confirmed that it does work as expected via curl.
Tested using version 2.3.0
Hi guys,
Just wondering if the CLI supports firewall filters: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/ and Cloudflare Access: https://api.cloudflare.com/#access-applications-list-access-applications ?
I couldn't see either listed in the readme.
Cheers
the json
keyword on the session put & post methods requires requests>=2.4.2. Old Ubuntu LTS versions ship with an older version which will cause an exception: CloudFlare.exceptions.CloudFlareAPIError: connection failed.
When executing cli4 -v --post expected_codes=2xx interval=15 retries=2 path=/status type=https /user/load_balancers/monitors
, I get a json: cannot unmarshal string into Go value of type uint
error as return. The example comes from the CTM Setup Instructions (load-balancing-early-access-guide-20161002.pdf), so the content should be valid.
Doing a POST to for an example /user/load_balancers/notifiers works, and creates a notifier as expected.
Is this likely to be a bug in cli4
, a problem with Cloudflare's API, or an error on my part?
Command output:
robert@butch ~/s/m/s/cloudflare-ctm> cli4 --version
Cloudflare library version: 1.3.2
robert@butch ~/s/m/s/cloudflare-ctm> cli4 -v --post expected_codes=2xx interval=15 retries=2 path=/status type=https /user/load_balancers/monitors
2016-11-29 10:04:37,744 - Python Cloudflare API v4 - DEBUG - Call: user/load_balancers/monitors,None,None,None,None
2016-11-29 10:04:37,744 - Python Cloudflare API v4 - DEBUG - Call: optional params and data None {'expected_codes': '2xx', 'path': '/status', 'interval': '15', 'type': 'https', 'retries': '2'}
2016-11-29 10:04:37,744 - Python Cloudflare API v4 - DEBUG - Call: method and url POST https://api.cloudflare.com/client/v4/user/load_balancers/monitors
2016-11-29 10:04:37,744 - Python Cloudflare API v4 - DEBUG - Call: headers {'X-Auth-Email': 'REDACTED', 'X-Auth-Key': 'REDACTED', 'Content-Type': 'application/json'}
2016-11-29 10:04:37,744 - Python Cloudflare API v4 - DEBUG - Call: doit!
2016-11-29 10:04:38,734 - Python Cloudflare API v4 - DEBUG - Call: done!
2016-11-29 10:04:38,738 - Python Cloudflare API v4 - DEBUG - Response: url https://api.cloudflare.com/client/v4/user/load_balancers/monitors
2016-11-29 10:04:38,738 - Python Cloudflare API v4 - DEBUG - Response: data {
"result": null,
"success": false,
"errors": [
{
"code": 6007,
"error": "json: cannot unmarshal string into Go value of type uint"
}
],
"messages": []
}
2016-11-29 10:04:38,739 - Python Cloudflare API v4 - DEBUG - Response: error 6007 json: cannot unmarshal string into Go value of type uint
cli4: /user/load_balancers/monitors - 6007 json: cannot unmarshal string into Go value of type uint
Python 3.6.9 and 3.5.2 (virtual envs, cloudflare-2.3.1)
$ cli4 -q /ips
Traceback (most recent call last):
File "/tmp/python3-venv-20191218/bin/cli4", line 8, in <module>
sys.exit(main())
File "/tmp/python3-venv-20191218/lib/python3.6/site-packages/cli4/__main__.py", line 13, in main
cli4(args)
File "/tmp/python3-venv-20191218/lib/python3.6/site-packages/cli4/cli4.py", line 367, in cli4
do_it(args)
File "/tmp/python3-venv-20191218/lib/python3.6/site-packages/cli4/cli4.py", line 362, in do_it
write_results(results, output)
File "/tmp/python3-venv-20191218/lib/python3.6/site-packages/cli4/cli4.py", line 199, in write_results
sys.stdout.write(results)
TypeError: write() argument must be str, not dict
Or python 2.7.12 (Ubuntu 16.04 w/ pip install cloudflare
, 2.3.1)
$ cli4 -q /ips
Traceback (most recent call last):
File "/usr/local/bin/cli4", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python2.7/dist-packages/cli4/__main__.py", line 13, in main
cli4(args)
File "/usr/local/lib/python2.7/dist-packages/cli4/cli4.py", line 367, in cli4
do_it(args)
File "/usr/local/lib/python2.7/dist-packages/cli4/cli4.py", line 362, in do_it
write_results(results, output)
File "/usr/local/lib/python2.7/dist-packages/cli4/cli4.py", line 199, in write_results
sys.stdout.write(results)
TypeError: expected a string or other character buffer object
The --quiet
option sets output
to None
, but write_results
doesn't handle this case. So in this example, results
is a dict, is not modified within write_results
, and so the call to sys.stdout.write
throws the above exception because it is not a string.
Expected results: --quiet
should not output anything, not even a newline
Hi,
Can you please provide an example of how to delete a specific DNS record (like a CNAME) from a given zone?
I checked the examples directory, the README and read the code, but I'm still not absolutely certain how this is done. Getting this wrong could mean accidentally deleting the entire zone instead of a specific DNS record so any help with this would be super appreciated.
Thanks,
Michael
yep
I make following request
for r in rules:
if r['actions'].pop()['id'] == 'always_use_https':
#switch_rules.append(r)
a = r['id']
cf.zones.pagerules.patch(zones['id'], a, params={'status:disabled'})
how to pass optional parameters ?
I got error like connection failed
Hi,
Take a look at this:
>>> my_domain = cf.zones.get(params = { 'name': 'xn--sanremomlheim-3ob.de' })
>>> my_domain[0]['name']
u'sanremom\u0102\u017alheim.de'
>>> my_domain = cf.zones.get(params = { 'name': 'sanremomülheim.de' })
>>> my_domain[0]['name']
u'sanremom\u0102\u017alheim.de'
>>> dns_records = cf.zones.dns_records.get(my_domain[0]['id'])
>>> dns_records[0]['name']
u'www.sanremom\xfclheim.de'
>>> print my_domain[0]['name']
sanremomĂźlheim.de
>>> print dns_records[0]['name']
www.sanremomülheim.de
The way the domain name is represented is different, sanremom\xfclheim.de
vs sanremom\u0102\u017alheim.de
.
Is this a bug?
How could I test if my_domain[0]['name']
is in dns_records[0]['name']
in python?
Thanks,
Max
cloudflare==2.1.0
requests==2.18.4
Using this module from inside China means that requests going to the Cloudflare API are quite unreliable. We find our code based on this module behaves consistently when run from outside of China, but in China will often hang for the first request, causing our script to run for a very long time. Since we run this script every minute on our ops server to update DNS records, if this script runs long, we will get an accumulation of instances running the script, which would eventually overload the server.
This one run got stuck for over 8 minutes:
^CTraceback (most recent call last):
File "/srv/managebac/shared/bin/cloudflare_update.py", line 100, in <module>
cf_zone = cf_get_zone(cf_client, zone_domain)
File "/srv/managebac/shared/bin/cloudflare_update.py", line 37, in cf_get_zone
zones = cf_client.zones.get(params={"name": zone_domain})
File "/usr/local/lib/python2.7/dist-packages/CloudFlare/cloudflare.py", line 618, in get
params, data)
File "/usr/local/lib/python2.7/dist-packages/CloudFlare/cloudflare.py", line 75, in call_with_auth
params, data, files)
File "/usr/local/lib/python2.7/dist-packages/CloudFlare/cloudflare.py", line 424, in _call
params, data, files)
File "/usr/local/lib/python2.7/dist-packages/CloudFlare/cloudflare.py", line 319, in _raw
params, data, files)
File "/usr/local/lib/python2.7/dist-packages/CloudFlare/cloudflare.py", line 188, in _network
data=data)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 521, in get
return self.request('GET', url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 440, in send
timeout=timeout
File "/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 601, in urlopen
chunked=chunked)
File "/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 346, in _make_request
self._validate_conn(conn)
File "/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 850, in _validate_conn
conn.connect()
File "/usr/local/lib/python2.7/dist-packages/urllib3/connection.py", line 284, in connect
conn = self._new_conn()
File "/usr/local/lib/python2.7/dist-packages/urllib3/connection.py", line 141, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "/usr/local/lib/python2.7/dist-packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
KeyboardInterrupt
real 8m9.595s
user 0m0.268s
sys 0m0.032s
The library should follow the advice from http://docs.python-requests.org/en/master/user/quickstart/#timeouts and set a default timeout for all requests, and, if possible, make this user-configurable.
You can tell Requests to stop waiting for a response after a given number of seconds with the timeout parameter. Nearly all production code should use this parameter in nearly all requests. Failure to do so can cause your program to hang indefinitely:
A "nice to have" would be for the library to retry failed requests using urllib's HTTPAdapter
. See http://docs.python-requests.org/en/master/_modules/requests/adapters/ and https://stackoverflow.com/a/15431343/3409092.
Per https://support.cloudflare.com/hc/en-us/articles/115003165991-Enterprise-Log-Share-ELS-Migrating-to-New-Endpoint, I should be able to pull down the list of defined fields for the received-time-ordered logs via cli4 --get /zones/:zone_id/logs/received/fields, but no go. I've even added the path entries to .cloudflare/cloudflare.cfg, and still no go. Initial error was "/zones/:zone_id/logs - not found", now I get "/zones/:zone_id/logs/received - not found".
I am trying to add MX records for some of my domains.
using the following
cli4 -v --post name="africlip.io" type="MX" PRIORITY=10 content="exch3.email.newsclip-sa.co.za" /zones/:africlip.io/dns_records
I keep getting the same error. I have tried various quoting options.
PRIORITY="10"
lower case priority=10
.
Same error every time
2019-07-24 15:28:28,421 - Python Cloudflare API v4 - DEBUG - Response: error 1004 DNS Validation Error
cli4: /zones/:africlip.io/dns_records - 1004 DNS Validation Error
2019-07-24 15:28:27,072 - Python Cloudflare API v4 - DEBUG - Call: zones,None,None,None,None,None
2019-07-24 15:28:27,072 - Python Cloudflare API v4 - DEBUG - Call: optional params and data {'name': 'africlip.io', 'per_page': 1} None
2019-07-24 15:28:27,072 - Python Cloudflare API v4 - DEBUG - Call: method and url GET https://api.cloudflare.com/client/v4/zones
2019-07-24 15:28:27,072 - Python Cloudflare API v4 - DEBUG - Call: headers {'User-Agent': 'python-cloudflare/2.3.0/python-requests/2.22.0/python/3.7.3', 'X-Auth-Email': '[email protected]', 'X-Auth-Key': 'REDACTED', 'Content-Type': 'application/json'}
2019-07-24 15:28:27,072 - Python Cloudflare API v4 - DEBUG - Call: doit!
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Call: done!
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Response: url https://api.cloudflare.com/client/v4/zones?name=africlip.io&per_page=1
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Response: 200, application/json, {"result":[{"id":"redacted","name":"africlip.io","status":"active","paused":false,"type":"full","development_mode":0,"name_servers":["hans.ns.cloudflare.com","melinda.ns.cloudflare.com"],"original_name_servers":["titan.is.co.za","jupiter.is.co.za","demeter.is.co.za"],"original_registrar":null,"original_dnshost":null,"modified_on":"2019-04-16T07:27:18.194789Z","created_on":"2019-01-16T06:54:13.079417Z","activated_on":"2019-01-18T18:56:56.812146Z","meta":{"step":3,"wildcard_proxiable":false,"custom_certificate_quota":0,"page_rule_quota":3,"phishing_detected":false,"multiple_railguns_allowed":false},"owner":{"id":"redacted","type":"user","email":"redacted"},"account":{"id":"redacted","name":"Newsclip Primary Account"},"permissions":["#access:edit","#access:read","#analytics:read","#app:edit","#auditlogs:read","#billing:read","#cache_purge:edit","#dns_records:edit","#dns_records:read","#lb:edit","#lb:read","#legal:read","#logs:edit","#logs:read","#member:read","#organization:edit","#organization:read","#ssl:edit","#ssl:read","#stream:edit","#stream:read","#subscription:edit","#subscription:read","#waf:edit","#waf:read","#webhooks:edit","#webhooks:read","#worker:edit","#worker:read","#zone:edit","#zone:read","#zone_settings:edit","#zone_settings:read"],"plan":{"id":"0feeeeeeeeeeeeeeeeeeeeeeeeeeeeee","name":"Free Website","price":0,"currency":"USD","frequency":"","is_subscribed":true,"can_subscribe":false,"legacy_id":"free","legacy_discount":false,"externally_managed":false}}],"result_info":{"page":1,"per_page":1,"total_pages":1,"count":1,"total_count":1},"success":true,"errors":[],"messages":[]}
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Response: [{'id': 'redacted', 'name': 'africlip.io', 'status': 'active', 'paused': False, 'type': 'full', 'development_mode': 0, 'name_servers': ['hans.ns.cloudflare.com', 'melinda.ns.cloudflare.com'], 'original_name_servers': ['titan.is.co.za', 'jupiter.is.co.za', 'demeter.is.co.za'], 'original_registrar': None, 'original_dnshost': None, 'modified_on': '2019-04-16T07:27:18.194789Z', 'created_on': '2019-01-16T06:54:13.079417Z', 'activated_on': '2019-01-18T18:56:56.812146Z', 'meta': {'step': 3, 'wildcard_proxiable': False, 'custom_certificate_quota': 0, 'page_rule_quota': 3, 'phishing_detected': False, 'multiple_railguns_allowed': False}, 'owner': {'id': 'redacted', 'type': 'user', 'email': '[email protected]'}, 'account': {'id': 'redacted', 'name': 'Newsclip Primary Account'}, 'permissions': ['#access:edit', '#access:read', '#analytics:read', '#app:edit', '#auditlogs:read', '#billing:read', '#cache_purge:edit', '#dns_records:edit', '#dns_records:read', '#lb:edit', '#lb:read', '#legal:read', '#logs:edit', '#logs:read', '#member:read', '#organization:edit', '#organization:read', '#ssl:edit', '#ssl:read', '#stream:edit', '#stream:read', '#subscription:edit', '#subscription:read', '#waf:edit', '#waf:read', '#webhooks:edit', '#webhooks:read', '#worker:edit', '#worker:read', '#zone:edit', '#zone:read', '#zone_settings:edit', '#zone_settings:read'], 'plan': {'id': '0feeeeeeeeeeeeeeeeeeeeeeeeeeeeee', 'name': 'Free Website', 'price': 0, 'currency': 'USD', 'frequency': '', 'is_subscribed': True, 'can_subscribe': False, 'legacy_id': 'free', 'legacy_discount': False, 'externally_managed': False}}]
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Call: zones,redacted,dns_records,None,None,None
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Call: optional params and data None {'name': 'africlip.io', 'type': 'MX', 'priority': '10', 'content': 'exch3.email.newsclip-sa.co.za'}
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Call: method and url POST https://api.cloudflare.com/client/v4/zones/redacted/dns_records
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Call: headers {'User-Agent': 'python-cloudflare/2.3.0/python-requests/2.22.0/python/3.7.3', 'X-Auth-Email': '[email protected]', 'X-Auth-Key': 'REDACTED', 'Content-Type': 'application/json'}
2019-07-24 15:28:27,744 - Python Cloudflare API v4 - DEBUG - Call: doit!
2019-07-24 15:28:28,420 - Python Cloudflare API v4 - DEBUG - Call: done!
2019-07-24 15:28:28,420 - Python Cloudflare API v4 - DEBUG - Response: url https://api.cloudflare.com/client/v4/zones/redacted/dns_records
2019-07-24 15:28:28,420 - Python Cloudflare API v4 - DEBUG - Response: 400, application/json, {"success":false,"errors":[{"code":1004,"message":"DNS Validation Error","error_chain":[{"code":9104,"message":"priority must be an int between 0 and 65535."}]}],"messages":[],"result":null}
I am not sure what else I can do here.
2019-07-24 15:28:28,421 - Python Cloudflare API v4 - DEBUG - Response: error 1004 DNS Validation Error
cli4: /zones/:africlip.io/dns_records - 1004 DNS Validation Error
cli4 -V
Cloudflare library version: 2.3.0
Let me know if I can provide any other details
The tests/ directory is not distributed on https://files.pythonhosted.org/packages/source/c/cloudflare/. Could you please distribute it?
I would like to be able to use Access Apps and Access Policy through the API client and the cli4 tool but it doesn't seem like it's in there.
If I wanted to add it myself is it just a matter of adding the right entries to to api_v4.py
?
It would be nice to keep PyPI releases and git tags in sync :)
I'm using PyCharm, how do I install it?
This module is not fully compatible with Python 3. There have been various attempts to fix this (c.f. #1, #3, #14, #21), but none of them have been merged and they were all incomplete. One particular area that hasn't been addressed in any of the pull requests is /examples
, which relies heavily on Python 2 behavior (primarily print
as a statement rather than a function). Please finish the migration to support Python 3. This is holding up packaging of the module for Fedora, which in turn is holding up packaging of the certbot-dns-cloudflare module for Fedora/EPEL.
Sample code to reproduce (replace relevant parts)
import CloudFlare
cf = CloudFlare.CloudFlare("[email]", "[key]")
zones = cf.zones.get(params={'name': "[domain]",'per_page': 1})
zone_id = zones[0]["id"]
print(cf.zones.dns_records.post(zone_id, data={'type': 'TXT', 'name': 'testtxt', 'content': 'test', 'ttl': 120}))
This bug will affect services that make use of TXT records (e.g. LetsEncrypt) when using the latest version of the Cloudflare module
I have a set of records that I am trying to create as CNAMEs in CloudFlare. Many of them are successful, however there are certain records that always fail to create and throw an error that is not terribly descriptive. I have found one reference to it in your codebase, but do not see why this error would be thrown for the same set of records everytime a call is attempted in trying to create them while other records succeed.
I have reached out to CloudFlare support, but they will not help since the error is coming from the Python module.
The error is: You must specify identifier1
. The requests are being made with a token as opposed to a username and password. The call being made is:
CF_TOKEN = '<string of API token>'
CF_ZONE = '<string of zone ID>'
cf = CloudFlare.CloudFlare(token=CF_TOKEN)
new_cname = {'name': '<string name of CNAME record>',
'type': 'CNAME',
'content': '<string value of CNAME record>',}
try:
cf.zones.dns_records.post(CF_ZONE, data=new_cname)
except CloudFlare.cloudflare.CloudFlareAPIError as e:
print('There was a problem creating the DNS validation record for {} '.format('<string name of CNAME record>' + str(e))
An example of a failing new_cname
dict is:
{'name': '_19b3a279aa2cb69039bd37c85c557c92.api.robinpowered.com.', 'type': 'CNAME', 'content': '_8d9d08826d5f4a56f590a47d674d5740.nhqijqilxf.acm-validations.aws.'}
Why would this record fail while others do not? Is there a better way to get a more useful error message?
here should be:
page_number = 1
From: https://api.cloudflare.com/#organizations-properties
NOTE: This API is deprecated, please use equivalent /accounts API endpoints where possible. Account APIs provide a broader range of features, and are backwards-compatible to organization APIs.
>>> cf.accounts.get()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'CloudFlare' object has no attribute 'accounts'
Hi!
I have the two sets of records in my zone: blablabla
and blablabla-cdn
. Content of all records are the same, for example:
Type | Name | Value |
---|---|---|
A | blablabla | 1.2.3.4 |
A | blablabla-cdn | 1.2.3.4 |
A | blablabla | 5.6.7.8 |
A | blablabla-cdn | 5.6.7.8 |
When I am trying to get this record via API I get the right number of blablabla-cdn
records, but an incorrect number of blablabla
records. I have 11 records in each set and I get 11 for blablabla-cdn
and 4 for blablabla
.
Here is code what I use:
cf = CloudFlare.CloudFlare(email=str(CF_API_EMAIL), token=str(CF_API_KEY))
dns_records = cf.zones.dns_records.get(zone_id)
for record in dns_records:
if (re.match('blablabla', record['name'])):
print(json.dumps(record,indent=4))
Is this a bug or I make something wrong?
Thanks!
Accordingly to the oficial documentation [1], the API call to purge specific URLs of a zone should return a dictionary like this one:
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "9a7806061c88ada191ed06f989cc3dac"
}
}
However, in the response object I'm receiving only the inner dictionary, the one that corresponds to the "result" key. I'm not receiving the parent dictionary with the other keys (success, errors, messages). Could this be a bug?
I'm using the version 2.1.0 of the library.
This is my code:
>>> r = cf.zones.purge_cache.post(
my_zone_id,
data={'files': [
'https://mydomain.com/image.jpg',
'http://mydomain.com/otherimage.jpg']
})
>>> print r
>>> {'id':'23fe45167b3dad00ae810cd597587da1'}
>>> print r.get('success')
>>> None
@gnowxilef commented on issue cloudflare-api/python-cloudflare-v4#17
@mahtin can you enable issues in the cloudflare repo?
Done!
DNS record deletion causes exception - it seems like API returns error, but without 'code' (it's not mandatory)
_raw() call returns {'error': 'You cannot use this API for domains with a .cf, .ga, .gq, .ml, or .tk TLD (top-level domain). To configure the DNS settings for this domain, use the Cloudflare Dashboard.'}
Exception trace:
In [10]: record = cf.zones.dns_records.get(zone['id'])[0]
In [11]: record['zone_id'], record['id']
Out[11]: ('9d2e3522d6f813a1d32c85d0fe137443', 'a47180b9c7daa2e8ec92fcc7a5fb2da8')
In [12]: zone = cf.zones.get(params={'name': '42cc-testing-site.tk'})[0]
In [13]: record = cf.zones.dns_records.get(zone['id'])[0]
In [14]: record['zone_id'], record['id']
Out[14]: ('9d2e3522d6f813a1d32c85d0fe137443', 'a47180b9c7daa2e8ec92fcc7a5fb2da8')
In [15]: cf.zones.dns_records.delete(record['zone_id'], record['id'])
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-15-06326d1a5ea4> in <module>
----> 1 cf.zones.dns_records.delete(record['zone_id'], record['id'])
~/.virtualenvs/pbn/lib/python3.6/site-packages/CloudFlare/cloudflare.py in delete(self, identifier1, identifier2, identifier3, params, data)
683 return self._base.call_with_auth('DELETE', self._parts,
684 identifier1, identifier2, identifier3,
--> 685 params, data)
686
687 class _AddWithAuthUnwrapped(object):
~/.virtualenvs/pbn/lib/python3.6/site-packages/CloudFlare/cloudflare.py in call_with_auth(self, method, parts, identifier1, identifier2, identifier3, params, data, files)
121 return self._call(method, headers, parts,
122 identifier1, identifier2, identifier3,
--> 123 params, data, files)
124
125 def call_with_auth_unwrapped(self, method, parts,
~/.virtualenvs/pbn/lib/python3.6/site-packages/CloudFlare/cloudflare.py in _call(self, method, headers, parts, identifier1, identifier2, identifier3, params, data, files)
486 if response_data['success'] is False:
487 errors = response_data['errors'][0]
--> 488 code = errors['code']
489 if 'message' in errors:
490 message = errors['message']
KeyError: 'code'
The examples are a bit outdated I believe, as I'm trying to write a supybot/limnoria plugin and I'm not able to get the package to load in any fashion other than to have it say that one or the other is not an attribute
import Cloudflare
class Cloudflare(callbacks.Plugin):
"""Allows access to the Cloudflare (tm) API"""
threaded = True
email = conf.supybot.plugins.Cloudflare.api.get('email')
key = conf.supybot.plugins.Cloudflare.api.get('key')
cf_send = Cloudflare.Cloudflare(email=email, token=key)
def zones(self, irc, msg, args):
"""takes no arguments
Lists the zones on the account."""
listofzones = cf_send.zones.get()
zonelist = []
for zone in listofzones:
zone_id = zone['id']
zone_name = zone['name']
zonelist.append("%s->%s" % (zone_id, zone_name))
irc.reply("%s" % (" \xB7 ".join(zonelist)), notice=True, private=True)
zones = wrap(zones, ['admin'])
Even when using import CloudFlare
as it says in the example, I get the following.
14:27 <~Ken> !load Cloudflare
14:27 <+ElectroCode> Ken: Error: No module named 'CloudFlare'
Here is a traceback using import Cloudflare as cf
File "/home/bots/electro/plugins/Cloudflare/plugin.py", line 53, in Cloudflare
cf_send = cf.CloudFlare(email=email, token=key)
AttributeError: module 'Cloudflare' has no attribute 'CloudFlare'
Hi,
the readme states that put is available for dns_records
-operations:
GET | PUT | POST | PATCH | DELETE | API call |
---|---|---|---|---|---|
(...) | (...) | (...) | (...) | (...) | (...) |
GET |
PUT |
POST |
DELETE |
/zones/:identifier/dns_records | |
(...) | (...) | (...) | (...) | (...) | (...) |
However when using dns_records.put()
(cf.zones.dns_records.put(zone_id, data=record)
) the SDK throws an error: CloudFlare.exceptions.CloudFlareAPIError: Method PUT not available for that URI.
At least the readme should be correct about the available methods, but ideally an idempotent PUT
should be available for dns_records
to avoid duplicate records.
Went to install the CloudFlare python library and was surprised it was pulling in a module for logging called logger
. Looked through the CF code and as best as i can tell it's not importing logger
anywhere, which is good b/c that module as a single .py and config file with the following which would mess up the logging config for most anything utilizing logging.
import logging
import logging.config
import os
import sys
import types
logging.getLogger('paramiko').setLevel(logging.WARNING)
logging.getLogger('requests').setLevel(logging.WARNING)
config_file = os.path.join(os.path.dirname(__file__), 'logging.conf')
logging.config.fileConfig(config_file, disable_existing_loggers=False)
logger = logging.getLogger()
def error(self, msg, *args, **kwargs):
self.error(msg, *args, **kwargs)
sys.exit(1)
logger.interrupt = types.MethodType(error, logger)
logger.info = logger.info
logger.warn = logger.warn
Pretty sure that line should just be dropped from the requirements list since everything being used is part of the stdlib.
hi,
I have an account of 206 domains, while I try to get the zone list using the API, even with 'per_page' set to 50, I found that there are 50 requests for the first 50 zones.
However, if I use 'curl' to get the data using the same API, all 50 results would be returned in one single request.
thanks
I'm using the cloudflare.zones.custom_hostnames.delete
endpoint and the endpoint throws a 500 error when a custom domain is in the state crypto.custom_hostnames.search.select.unknown_state
. Instead, this should be caught and rethrown as a CloudFlareError
so that all errors can be caught without specifying multiple exception classes.
HTTPError: 500 Server Error: Internal Server Error for url: https://api.cloudflare.com/client/v4/zones/...
I trying to use this api method, but i get error:
Traceback (most recent call last):
File "Projects/tg/cloudflare_bot/main.py", line 138, in <module>
pprint(cf.get_fw_rules(data['id']))
File "Projects/tg/cloudflare_bot/main.py", line 28, in get_fw_rules
return self.zones.firewall.rules.get(identifier)
AttributeError: '_add_unused' object has no attribute 'rules'
Code:
class CFAPI(CloudFlare):
def __init__(self, token, email):
super().__init__(token=token, email=email, debug=True)
def get_fw_rules(self, identifier):
#print(dir(self.zones.firewall))
return self.zones.firewall.rules.get(identifier)
cf = CFAPI(CLOUDFLARE_API, CLOUDFLARE_EMAIL)
pprint(cf.get_fw_rules(data['id']))
I tried to check this with dir(self.zones.firewall), but I didn’t get rules in the list. Can you fix this?
Hi,
I'm trying to call the dns_records/import
endpoint using this python lib, but I can't find how to do it.
Please someone provide an example (add this one to examples directory).
Regards
Hi,
First time user of this module, with v. 2.3.0 from pypi.
I am doing the very simple example of listing zones. I generated an API token.
def get_cf_dns(cftoken):
cf = CloudFlare.CloudFlare(debug=True, token=cftoken)
zones = cf.zones.get()
for zone in zones:
zone_id = zone['id']
zone_name = zone['name']
print(zone_id, zone_name)
The output throws me off with
2019-10-21 19:58:22,764 - Python Cloudflare API v4 - DEBUG - Response: url https://api.cloudflare.com/client/v4/zones
2019-10-21 19:58:22,764 - Python Cloudflare API v4 - DEBUG - Response: 400, application/json, {"success":false,"errors":[{"code":6003,"message":"Invalid request headers","error_chain":[{"code":6103,"message":"Invalid format for X-Auth-Key header"}]}],"messages":[],"result":null}
2019-10-21 19:58:22,764 - Python Cloudflare API v4 - DEBUG - Response: error 6003 Invalid request headers
Traceback (most recent call last):
File "./main.py", line 39, in <module>
get_cf_dns(cftoken)
File "./main.py", line 30, in get_cf_dns
zones = cf.zones.get()
File "/home/xxx/.virtualenvs/cloudflare_vault_py-a7RkIZod/lib/python3.7/site-packages/CloudFlare/cloudflare.py", line 618, in get
params, data)
File "/home/xxx/.virtualenvs/cloudflare_vault_py-a7RkIZod/lib/python3.7/site-packages/CloudFlare/cloudflare.py", line 75, in call_with_auth
params, data, files)
File "/home/xxx/.virtualenvs/cloudflare_vault_py-a7RkIZod/lib/python3.7/site-packages/CloudFlare/cloudflare.py", line 467, in _call
raise CloudFlareAPIError(code, message, error_chain)
CloudFlare.exceptions.CloudFlareAPIError: Invalid request headers
It's talking about the X-Auth-Key header, whereas I am guessing it should not since it is really a token and I am not passing any email parameter?
I validated my token against CF with curl, all good and sound:
{
"result": {
"id": "xxx",
"status": "active"
},
"success": true,
"errors": [],
"messages": [
{
"code": 10000,
"message": "This API Token is valid and active",
"type": null
}
]
}
Thanks.
Python 3.8 is now displaying warnings when is
is used with a literal.
Here are the warnings with 2.4.0:
/usr/lib/python3.8/site-packages/CloudFlare/cloudflare.py:839: SyntaxWarning: "is" with a literal. Did you mean "=="?
if email is '':
/usr/lib/python3.8/site-packages/CloudFlare/cloudflare.py:841: SyntaxWarning: "is" with a literal. Did you mean "=="?
if token is '':
/usr/lib/python3.8/site-packages/CloudFlare/cloudflare.py:843: SyntaxWarning: "is" with a literal. Did you mean "=="?
if certtoken is '':
See python/cpython#9642 for more info
I am also submitting a PR with a fix.
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.