Cloudflare dynamic dns with python

Here is some Python 3 code for changing a dns record with the Cloudflare V4 api.
It is mostly intended as an example, so I tried to keep it as basic as possible. Hence the lack of objects and use of global variables.

import urllib.request
import urllib.parse
import json
import tempfile
import os.path

#User-editable variables
login_email = 'changeme@gmail.com'
api_key = 'changeme'
domain = 'changeme.com'
record = 'changeme'

#Value in seconds, you can only use the same timespans as in the control panel. Set to None if you want the 'Automatic' setting.
ttl = 120

#End of user-editable variables

zone_id = ''
record_id = ''

base_url = 'https://api.cloudflare.com/client/v4/zones'

filename = 'cf_dns.json'
tempdir = tempfile.gettempdir()
datapath = os.path.join(tempdir, filename)

def store_data():
    data = {
        'domain' : domain,
        'record' : record,
        'zone_id' : zone_id,
        'record_id' : record_id
    }
    with open(datapath, 'w') as datafile:
        json.dump(data, datafile)

def get_data():
    global zone_id
    global record_id
    try:
        with open(datapath) as datafile:
            data = json.load(datafile)
    except FileNotFoundError:
        data = []
    if data:
        if (data['domain'] == domain) and (data['record'] == record):
            zone_id = data['zone_id']
            record_id = data['record_id']

def get_ip():
    ip_fetch_url = 'http://icanhazip.com/'
    with urllib.request.urlopen(ip_fetch_url) as response:
        ip = response.read().decode("utf-8").strip()
    return ip

def send_query(url, method, data=None):
    headers = {'X-Auth-Email' : login_email,
               'X-Auth-Key' : api_key,
               'Content-Type' : 'application/json' }

    if data:
        data = json.dumps(data).encode('utf8')
    req = urllib.request.Request(url, data, headers, method=method)
    with urllib.request.urlopen(req) as response:
        output = response.read()
    ret = json.loads(output.decode("utf-8"))
    return ret

def get_id(url):
    ret = send_query(url, 'GET')
    id_number = ret['result'][0]['id']
    return id_number

def update_record():
    values = {'type' : 'A',
              'name' : record,
              'content' : get_ip(),
              'ttl' : ttl }

    url = "{0}/{1}/dns_records/{2}".format(base_url, zone_id, record_id)
    return send_query(url, 'PUT', values)

get_data()

if not zone_id:
    url = "{0}?name={1}".format(base_url, domain)
    zone_id = get_id(url)
    print("This is your zone id: ", zone_id)

if not record_id:
    url = "{0}/{1}/dns_records?name={2}.{3}".format(base_url, zone_id, record, domain)
    record_id = get_id(url)
    print("This is your record id: ", record_id)

response = update_record()

if response['success']:
    print("Record updated successfully")

store_data()

Comments are closed.