Package: pyCZDS
pyCZDS – A Python client for ICANN's Centralized Zone Data Service (CZDS) APIThis package allows you to seamlessly interact with ICANN's CZDS in Python, and download zone files for participating top level domains (e.g., .com, .net, and many others).The Centralized Zone Data Service (CZDS) is an online portal where any interested party can request access to the Zone Files provided by participating generic Top-Level Domains (gTLDs).(source)Relevant links:ICANN CZDS homepagepyCZDS onPyPIpyCZDS repo onGitHubInstallationThis package requires Python 3 and has been tested with Python 3.10.8. It requires therequestspackage.
The library implements a client against the official API documentation which can be found under thislink.Install pyCZDS with the commandpip install pyCZDS.Exemplary flow1. Create a new CZDSClientfrom pyczds.client import CZDSClient

# replace username and password with actual credentials
c = CZDSClient(username, password)2. Retrieve all URLs for the zone files accessible under the accountzonefile_urls = c.get_zonefiles_list()3. From the list of URLs, select the zone file of interestcom_zonefile_url = next((url for url in zonefile_urls if "com.zone" in url), None)4. Optionally, inspect the current header of the selected zonefileThis is useful if, for example, you have downloaded the zonefile for a zone previously and want to understand if it has been updated in the meantime.from datetime import datetime, timezone

com_zonefile_headers = c.head_zonefile(com_zonefile_url)

# check if the zonefile is from today
com_zonefile_headers['parsed']['last-modified'].date() == datetime.now(timezone.utc).date()5. Download the zonefileThe following command will download the zone file for the .com zone in the current directory to the file "com.txt.gz".c.get_zonefile(com_zonefile_url)Detailed descriptionUsageThe library supports the following actions:client.get_zonefiles_list– retrieves the download links for all zone files the respective account is authorized to access;client.head_zonefile– retrieves the headers for a specified zone file, which contain metadata such as the last modified timestamp and the file's size;client.get_zonefile– downloads a specified zone file.Instantiating a clientUse the following pyCZDS – An API client for ICANN's Centralized Zone Data Service (CZDS)code to create a newCZDSClientobject:from pyczds.client import CZDSClient

# replace username and password with actual credentials
c = CZDSClient(username, password)The client handles the authentication with the API transparently. It will authenticate with the first call of any method, and will retain the acquired token for subsequent requests. When the token expires, it will renew the authentication automatically.Getting zone file download URLsThe following command will retrieve a list of all zone files the account is authorized to access. It returns alistwith the respective URLs.print(c.get_zonefiles_list())
# [
    'https://czds-download-api.icann.org/czds/downloads/net.zone',
    ...
    'https://czds-download-api.icann.org/czds/downloads/com.zone'
]Access to additional zone files can be requested online under thislink.Requesting the headers for a zone fileUsing one of the links received viaget_zonefiles_list(), the following command retrieves the headers for a specified zonefile. It returns adict(more specifically, arequests.models.CaseInsensitiveDict):print(c.head_zonefile('https://czds-download-api.icann.org/czds/downloads/vision.zone'))
# {
    'Date': 'Fri, 16 Dec 2022 19:42:58 GMT',
    ...
    'Last-Modified': 'Fri, 16 Dec 2022 01:29:08 GMT',
    ...
    'Content-Disposition': 'attachment;filename=vision.txt.gz',
    ...
    'Content-Length': '602034',
    ...
}To facilitate further work with the metadata, the dictionary not only contains the raw HTTP headers, but also a subdictparsed(which is arequests.models.CaseInsensitiveDict, too), which contains a selection of the headers parsed in suitable data types:print(c.head_zonefile('https://czds-download-api.icann.org/czds/downloads/vision.zone'))
# {
    'Last-Modified': 'Sat, 17 Dec 2022 00:17:25 GMT',
    'Content-Disposition': 'attachment;filename=net.txt.gz',
    'Content-Length': '481167941',
    ...
    'parsed': {
        'last-modified': datetime.datetime(2022, 12, 17, 0, 17, 25, tzinfo=datetime.timezone.utc),  # datetime.datetime
        'content-length': 481167941,  # int
        'filename': 'net.txt.gz'  # string
    }
}Having the values available in parsed form makes it easier to compare different headers of a zone file. For example, you can easily determine whether a zonefile has been updated since the last retrieval by comparing:headers_old['parsed']['last-modified'] < headers_new['parsed']['last_modified']
# TrueDownloading a zone fileThe following command will download a specified zone file:c.get_zonefile('https://czds-download-api.icann.org/czds/downloads/vision.zone', download_dir='zonefiles/', filename='vision_zonefile')The following parameters are optional:download_dirsets the local directory where the file should be downloaded to. If it is not passed, the file will be downloaded to the working directory of your script.filenamesets the local filename of the downloaded file. If it is not passed, the filename will be set according to the value the API provides in theContent-Dispositionheader, e.g.,vision.txt.gz.TroubleshootingShould you encounter any errors, a good first step is to increase the logging level todebugand then analyze the output.import logging

from pyczds import client

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

# Run the problematic command
c = client.CZDSClient(username, password)TestsThe entire codebase is covered. Run the test from thetestsdirectory. Before you do so, make sure you setusernameandpasswordintests/test_pyczds.py:class TestPyCZDS(unittest.TestCase):
    def setUp(self):
        # In order to run these tests, enter your valid username and password for the CZDS website here.
        # Please note that these tests do not change any data.

        # TODO PASTE USERNAME AND PASSWORD HERE
        username = ''
        password = ''
        # END TODOLegal disclaimerI am a hobby enthusiast and am neither affiliated with ICANN, nor is this library endorsed by ICANN.Links and further informationWikipedia – Zone fileCZDS – LoginCZDS – HelpCZDS – Request access to additional hostfiles