Python Connect with API

In this lesson, we’ll take a look at how we can use Python to communicate with an Application Programming Interface (API). An API is a software interface that allows applications to communicate with other applications. In our case, we are going to communicate with an API using Python.

We are going to use the Python requests module. With this module, you can send all sorts of HTTP requests. Let’s install it with PIP:

pip install requests

We’ll try different APIs so we can test different things:

  • API without authentication: the most simple API to work with, great to learn the basics.
  • API with query parameters: we can use this to send parameters to the API.
  • API with authentication: most APIs require authentication. I’ll show you an example of how to authenticate with an API.

API without Authentication

When you try to communicate with an API for the first time in Python, you want to make sure you try an API that is simple to understand and has decent documentation. If possible, the API shouldn’t have authentication so you don’t have to worry about authentication methods like tokens, API keys, OAuth, etc.

One such API is the Date Nager API. You can use this API to fetch public holidays for any country and year. It’s a simple API that doesn’t require authentication and has decent documentation.

Here is my sample code:

import requests

response = requests.request('GET', "https://date.nager.at/api/v3/publicholidays/2026/US")

if response.status_code == 200:
    print("Succesful connection with API.")
    data = response.json()
elif response.status_code == 404:
    print("Unable to reach URL.")
else:
    print("Unable to connect API or retrieve data.")

for record in data:
    print(record['name'])

Will show this output:

Succesful connection with API.
New Year's Day
Martin Luther King, Jr. Day
Lincoln's Birthday
Presidents Day
Good Friday
Good Friday
Truman Day
Memorial Day
Juneteenth National Independence Day
Independence Day
Labour Day
Columbus Day
Indigenous Peoples' Day
Veterans Day
Thanksgiving Day
Christmas Day

Let me explain the code above:

  • We use the requests module to send an HTTP GET request to:
    • https://date.nager.at/api/v3/publicholidays/2026/US.
  • The API responds with HTTP status code 200 when we are able to connect.
  • The API returns the requested data in JSON format. We format JSON to a Python dictionary and store it in variable “data”.
  • When the API can’t find the requested content, it returns an HTTP status code 404.
  • When the API returns any other HTTP status code, we know something went wrong.
  • We iterate our dictionary and print all keys with “name”.

Excellent. We now have a list of all US public holidays in 2026.

Query Parameters

Let’s move on with a slightly more advanced example. This time we use the Datamuse API. This API is a word-finding query engine. It lets you send queries to find words that match certain criteria. Not something we as network engineers probably need, but it’s a great way to test query parameters and Datamuse offers good documentation.

For example, let’s say I want to find words that rhyme with the word “network”. You can use the following URL for this:

https://api.datamuse.com/words?rel_rhy=network

Go ahead and open the link above in your web browser. The part in the URL after the ? is the query parameter.

Let’s see if we can communicate with this API in Python:

import requests

response = requests.request('GET', "https://api.datamuse.com/words?rel_rhy=network")

if response.status_code == 200:
    print("Succesful connection with API.")
    data = response.json()
elif response.status_code == 404:
    print("Unable to reach URL.")
else:
    print("Unable to connect API or retrieve data.")

for record in data:
    print(record['word'])

Will show this output:

Succesful connection with API.
smirk
jerk
work
framework
lurk
dirk
murk
berserk
burke
cirque
shirk
groundwork
artwork
quirk
fieldwork
masterwork
berk
perk
soda jerk
piece of work
merck
teamwork
handiwork
patchwork
field work
line of work
werke
woodwork
kirk
clockwork
homework
latticework
metalwork
spadework
birk
merc
desk clerk
body of work
turk
earthwork
firework
paperwork
brushwork
schoolwork
plasterwork
burk
legwork
erk
file clerk
detective work
bank clerk
reference work
filing clerk
mail clerk
do work
undercover work
sherk
berke
overwork
rework
piecework
needlework
social work
housework
guesswork
footwork
town clerk
openwork
casework
beadwork
clean and jerk
at work
merk
booking clerk
literary work
roadwork
shipping clerk
perc
ataturk
room clerk
werk
put to work
tally clerk
electrical work
waterwork
bead and quirk
dramatic work
shop clerk
hotel desk clerk
hotel clerk
kurk
ferch
zirk
berch
leadwork
wallwork
agrokomerc
bjerke
bourke
burck

The code above is very similar to our first example. I use the requests module to send an HTTP GET request to the URL. The code above works, but we can improve it in a more pythonic way.

Pythonic means that you use code that follows the best practices for Python and use it the way it is intended to be used.

Let’s try something else. Here is my code:

import requests

query_parameters = {"rel_rhy":"network"}
response = requests.get("https://api.datamuse.com/words", query_parameters)

if response.status_code == 200:
    print("Succesful connection with API.")
    data = response.json()
elif response.status_code == 404:
    print("Unable to reach URL.")
else:
    print("Unable to connect API or retrieve data.")

for record in data:
    print(record['word'])

Will show this output:

Succesful connection with API.
smirk
jerk
work
framework
lurk
dirk
murk
berserk
burke
cirque
shirk
groundwork
artwork
quirk
fieldwork
masterwork
berk
perk
soda jerk
piece of work
merck
teamwork
handiwork
patchwork
field work
line of work
werke
woodwork
kirk
clockwork
homework
latticework
metalwork
spadework
birk
merc
desk clerk
body of work
turk
earthwork
firework
paperwork
brushwork
schoolwork
plasterwork
burk
legwork
erk
file clerk
detective work
bank clerk
reference work
filing clerk
mail clerk
do work
undercover work
sherk
berke
overwork
rework
piecework
needlework
social work
housework
guesswork
footwork
town clerk
openwork
casework
beadwork
clean and jerk
at work
merk
booking clerk
literary work
roadwork
shipping clerk
perc
ataturk
room clerk
werk
put to work
tally clerk
electrical work
waterwork
bead and quirk
dramatic work
shop clerk
hotel desk clerk
hotel clerk
kurk
ferch
zirk
berch
leadwork
wallwork
agrokomerc
bjerke
bourke
burck

In the code above, I separated the URL from the query parameter. We also use requests.get instead of requests.request now.

The output is exactly the same, but our code looks a bit cleaner because of the separate query parameter.

Instead of using the requests library, you could use some other module. For example, Datamuse has a Python module. These modules usually use the requests module under the hood and abstract away some of the complexity.

Using modules has both pros and cons. The advantage of a module is that it’s usually quicker to build something. The disadvantage is that some modules might work today, but won’t be maintained in the future.

For example, if you want to communicate with the Twitter API you could build something from scratch or use a popular module. an example such as Tweety.

In the case of Tweety, this module has been out there for 8 years and is well maintained.  If you find a module and the last time someone worked on it was over two years ago, it might be better to skip it and use the requests library directly. You can still look at the code and use parts of the module as inspiration for your own code.

API Authentication

Let’s move on to the next example. How about an API that requires authentication? I won’t cover every possible authentication method, but I do have a nice example that is network-related. How about we communicate with Cisco’s DNA Center API ? Cisco has a sandbox environment for DNA Center. You can communicate with their API without registration.

I kept my sample code as short as possible, no if/else or try/except blocks so we can focus completely on the authentication part. Here is the code:

import requests
from requests.auth import HTTPBasicAuth  # DNA Center uses basic authentication.
import urllib3

# Disable HTTPS insecure certificate warning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

username = "devnetuser"
password = "Cisco123!"

def get_token(username, password):
    """
    Authenticate to DNA Center and get token.
    """
    url = "https://sandboxdnac.cisco.com/api/system/v1/auth/token"

    # API uses JSON.
    headers = {'content-type': 'application/json'}
    # Send HTTP POST with username and password.
    response = requests.request("POST",
                                url, 
                                auth=HTTPBasicAuth(username, password),
                                headers=headers, verify=False)
    
    # Save the token in a variable.
    token = response.json()["Token"]
    return token


def get_data_from_dna_center(token, endpoint):
    """
    Communicate with DNA Center to retrieve network information.
    """

    # Include the token in the header.
    headers = {'content-type': 'application/json', 'x-auth-token': token}
    # Send HTTP GET to retrieve endpoint.
    response = requests.get('https://sandboxdnac.cisco.com/api/v1/%s' % endpoint, headers=headers, verify=False)
    response_as_dict = response.json() # convert JSON to DICT.
    return response_as_dict

# Run function to authenticate and get token.
token = get_token(username, password)
# Retrieve list with network devices of DNA center.
network_devices_info = get_data_from_dna_center(token, "network-device")

# Print list with network devices.
for device in network_devices_info['response']:
    device_type = device['type']
    uptime = device['upTime']

    print("Device: %s has an uptime of %s." % (device_type, uptime))

Will show this output:

Device: Cisco Catalyst 9000 UADP 8 Port Virtual Switch has an uptime of 20 days, 1:13:51.00.
Device: Cisco Catalyst 9000 UADP 8 Port Virtual Switch has an uptime of 20 days, 1:13:41.00.
Device: Cisco Catalyst 9000 UADP 8 Port Virtual Switch has an uptime of 20 days, 1:13:47.00.
Device: Cisco Catalyst 9000 UADP 8 Port Virtual Switch has an uptime of 20 days, 1:13:36.00.

Let me explain the code above:

  • We have two functions:
    • The get_token function authenticates with DNA Center:
      • We send an HTTP POST request which includes the username, password, and a header which specifies that we use the JSON format.
      • When the DNA Center API authenticates us successfully, the API returns a token that we need to use for any other requests.
      • We store the token in the “token” variable.
    • The get_data_from_dna_center function retrieves data from DNA Center:
      • We send an HTTP GET request which includes a header with our token.
      • The base URL for this API is HTTPS://sandboxdnac.cisco.com/api/v1
      • The “endpoint” defines the data that we want to retrieve.

Excellent. We get a list of network devices and their uptime.

Unlock This Lesson for Free - No Credit Card Needed!

If you like to keep on reading, register now!

  • Learn CCNA, CCNP and CCIE R&S. Explained As Simple As Possible.
  • Get Instant Access to this Full Lesson, Completely for Free!
  • Unlock More to Read. More Lessons Added Every Week!
  • Content created by Rene Molenaar (CCIE #41726)
2296 Sign Ups in the last 30 days

Forum Replies

  1. Do you have any experience with opendcim?
    I’m looking to update devices via python using APIs

    Can you give me any examples to do this?

    Thanks

  2. Hello Giovanni

    This lesson describes how to connect via Python using APIs:

    https://networklessons.com/python/python-connect-with-api

    Although it does not use openDCIM, it gives you an idea of the methodology used. If you want to specifically use openDCIM, there’s a lot of documentation out there from the very simple to the complex. A good place to start may be the following Getting Started info about openDCIM.

    If you would like to see openDCIM or any other feature or tool on the site, you can always make a suggestion at the Member Ideas page below:

    https://ne

    ... Continue reading in our forum

  3. Hello,
    I am a bit confused. Are these APIs in the lesson considered as REST? For example, in the “API without Authentication” example, it is said “The API returns the requested data in JSON format.”
    Isn’t this the Representational part of a REST API?
    Thanks.

  4. Hello Marios

    These are not REST APIs, but I understand that the title of this particular thread is Python Connect with REST API. This is a typo. The lesson itself is called Python Connect with API. For REST APIs, take a look at this lesson:

    https://networklessons.com/cisco/ccna-200-301/introduction-to-rest-api

    REST APIs typically use HTTP methods to retrieve or send information between applications. REST APIs in the context of the above lesson are APIs to Cisco network devices for the purpose of controlling and managing them.

    I will let Rene know to make th

    ... Continue reading in our forum

Ask a question or join the discussion by visiting our Community Forum