Subscribe to receive notifications of new posts:

python-cloudflare

2016-05-09

3 min read

Using the CloudFlare API via Python

Very early on in the company’s history we decided that everything that CloudFlare does on behalf of its customer-base should be controllable via an API. In fact, when you login to the CloudFlare control panel, you’re really just making API calls to our backend services. Over time that API has matured and improved. We are now on v4 of that API.

The current CloudFlare API is documented here and it’s used by both the CloudFlare control panel and directly by umpteen customers every minute of every day. The new API is designed with a clean naming structure and consistent data representation for data. It’s also extensible.

This blog entry introduces python-cloudflare, a Python wrapper providing full access to the CloudFlare v4 API.

An example

Let’s get right into the thick-of-it with the simplest coding example available to show python-cloudflare in action. This example lists all your domains (zones) and also checks some basic features for each zone.

#!/usr/bin/env python
import CloudFlare
def main():
    cf = CloudFlare.CloudFlare()
    zones = cf.zones.get(params={'per_page':50})
    for zone in zones:
        zone_name = zone['name']
        zone_id = zone['id']
        settings_ipv6 = cf.zones.settings.ipv6.get(zone_id)
        ipv6_on = settings_ipv6['value']
        print zone_id, ipv6_on, zone_name
    exit(0)
if __name__ == '__main__':
    main()

The structure of the CloudFlare class matches the API documentation. The CloudFlare.zones.get() method returns information about the zones as per the list zones documentation. The same for CloudFlare.zones.settings.ipv6.get() and its documentation.

Data is passed into the methods via standard Python structures and they are returned in Python structures that match the API documentation. That means if you see an API call in the documentation, then you can translate it into the Python code in a one-to-one manner.

For example, take a look at the WAF list rules API call.

alt

This codes into CloudFlare.zones.dns_records.post() method with the zone_id as the first argument, the package_id as the second argument and the optional parameters passed last (or if there aren’t any; then just drop the third argument for the call). Because this is a GET call there’s a .get() as part of the method name.

    r = cf.zones.firewall.waf.packages.rules.get(zone_id, package_id, params=params)

Here’s the much simpler Create DNS record API call.

alt

This would be coded into the Python method CloudFlare.zones.dns_records.post() with the zone_id as the first argument and the required parameters passed as data. Because this is a POST call there’s a .post() as part of the method name.

    r = cf.zones.dns_records.post(zone_id, data=dns_record)

Here’s an example of that Create DNS record call in action. In this code, we add two records to an existing zone. We also show how the error is handled (in classic Python style).

    zone_name = 'example.com'
    try:
        r = cf.zones.get(params={'name': zone_name})
    except CloudFlare.CloudFlareAPIError as e:
        exit('/zones.get %s - %d %s' % (zone_name, e, e))
    except Exception as e:
        exit('/zones.get %s - %s' % (zone_name, e))
   zone_id = r['id']
   # DNS records to create
    dns_records = [
        {'name':'foo', 'type':'A',    'content':'192.168.100.100'}
        {'name':'foo', 'type':'AAAA', 'content':'2001:d8b::100:100'},
    ]
    for dns_record in dns_records:
        try:
            r = cf.zones.dns_records.post(zone_id, data=dns_record)
        except CloudFlare.CloudFlareAPIError as e:
            exit('/zones.dns_records.post %s - %d %s' % (record['name'], e, e))

There’s a whole folder of example code available on the GitHub repository.

All on GitHub for anyone to use

As we stated above (and as CloudFlare has done many times before) we have placed this code up on GitHub for anyone to download and use. We welcome contributions and will review any pull requests. To install it, just clone it and follow the README instructions. For those that just want to get going right now; here’s the tl;dr install:

$ git clone https://github.com/cloudflare/python-cloudflare
$ cd python-cloudflare
$ ./setup.py build
$ sudo ./setup.py install

But wait; there’s more!

Not only do you get the python API calls, you also get a fully functioning CLI (command line interface) that allows quick creation of scripts that interface with CloudFlare.

From the CLI command you can call any of the CloudFlare API calls. The command responds with the returned JSON data. If you want to filter the results you possibly also want to install the highly-versatile jq command. Here’s a command to check the nameservers for a specific domain hosted on CloudFlare and then process it via jq.

$ cli4 name=example.com /zones | jq -c '.[]|{"name_servers":.name_servers}'
{
  "name_servers":[
    "alice.ns.cloudflare.com",
    "bob.ns.cloudflare.com"
  ]
}
$

The CLI command will convert on-the-fly zone names into zone identifiers. For example; if you want to check the DNSSEC status on a zone your operate on CloudFlare; then use this command.

$ cli4 /zones/:example.com/dnssec | jq '{"status":.status,"ds":.ds}'
{
  "status": "active",
  "ds": "example.com. 3600 IN DS 2371 13 2 00000000000000000000000000000 ..."
}
$

You can issue GET PUT POST PATCH or DELETE calls into the API. You can pass data into a CloudFlare API call with the CLI command. All documented via the README.md and wiki examples in GitHub.

Here’s a useful command for customers that need to flush their cache files.

$ cli4 --delete purge_everything=true /zones/:example.com/purge_cache
{
  "id":"d8afaec3dd2b7f8c1b470e594a21a01d"
}
$

See how the commands arguments match the purge_cache API documentation.

alt

Finally, here’s an example of turning on DNSSEC via the API.

$ cli4 --patch status=active /zones/:example.com/dnssec | jq -c '{"status":.status}'
{"status":"pending"}
$

There are plenty more examples available within the GitHub repo.

CloudFlare API via other languages also available

Python isn’t the only language you can use to interact with CloudFlare’s API. If you’re a Go, or Node.js user, we also have client libraries you can use to interact with CloudFlare on our GitHub. Find them here Go client and here Node.js client. Want to write something in a different language? Feel free to do that. The API spec is online and ready for you to code up.

If you like what you read here today and are interested in joining one of CloudFlare’s software teams, then checkout our Join Our Team page.

Cloudflare's connectivity cloud protects entire corporate networks, helps customers build Internet-scale applications efficiently, accelerates any website or Internet application, wards off DDoS attacks, keeps hackers at bay, and can help you on your journey to Zero Trust.

Visit 1.1.1.1 from any device to get started with our free app that makes your Internet faster and safer.

To learn more about our mission to help build a better Internet, start here. If you're looking for a new career direction, check out our open positions.
APIWAF RulesWAFDNSSECDNSPythonProgramming

Follow on X

Martin J Levy|@mahtin
Cloudflare|@cloudflare

Related posts

September 24, 2024 1:00 PM

Automatically generating Cloudflare’s Terraform provider

The Cloudflare Terraform provider used to be manually maintained. With the help of our existing OpenAPI code generation pipeline, we’re now automatically generating the provider for better endpoint and attribute coverage, faster updates when new products are announced and a new API documentation site to top it all off. Read on to see how we pulled it all together....

September 24, 2024 1:00 PM

Cloudflare partners with Internet Service Providers and network equipment providers to deliver a safer browsing experience to millions of homes

Cloudflare is extending the use of our public DNS resolver through partnering with ISPs and network providers to deliver a safer browsing experience directly to families. Join us in protecting every Internet user from unsafe content with the click of a button, powered by 1.1.1.1 for Families....