1
\$\begingroup\$

Please check over my Python code for a HTTP GET operation using the requests library, and provide any potential pointers for improvement.

import requests

token = input()

payload={}

headers = {
    "Accept": "application/yang-data+json",
    "Content-Type": "application/yang-data+json",
    "Authorization": "Bearer {}".format(token),
}

url = "https://sandbox-xxxx.cisco.com/restconf/data/native/router/bgp"


try:
    response = requests.get(url, headers=headers, data=payload, verify=False, timeout=10)
except requests.exceptions.HTTPError as errh:
    print(f"An HTTP Error occured: {errh}")
except requests.exceptions.ConnectionError as errc:
    print(f"An Error Connecting to the API occured: {errc}")
except requests.exceptions.Timeout as errt:
    print(f"A Timeout Error occured: {errt}")
except requests.exceptions.RequestException as err:
    print(f"An Unknown Error occured: {err}")
else:
    print(response.status_code)
    print(response.json())
New contributor
pythontestuser is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
4
  • \$\begingroup\$ Thank you so much for the response, Reinderien. I am just starting in Python so please excuse any "noobness" from myself. This is just a cisco IOS-XE device I am testing on in the lab where code runs fine and with no issues without any exceptions, I just wanted to add some exceptions in to make my code as optimal as possible. There is a load of different and conflicting info out there, so I thought I would cobble together what I thought and ask some experts for their own opinion rather than some random online blog. \$\endgroup\$ May 12 at 20:17
  • \$\begingroup\$ Thank you for understanding. I have updated my original response to include the full code. I am just trying to get a decent set of exceptions that I could then apply to any future HTTP requests. I did read about what you mention about a form of catch all is not a good idea, so this is what prompted me to put my first post up on here. \$\endgroup\$ May 13 at 9:35
  • \$\begingroup\$ This doesn't execute, right? my_url and url are two different variables \$\endgroup\$
    – Reinderien
    May 13 at 12:49
  • \$\begingroup\$ It does execute. Apologies, That was a mistake on my part, I have edited the code again. \$\endgroup\$ May 13 at 17:14

1 Answer 1

4
\$\begingroup\$

Since this is the entire script,

  1. it doesn't need to exist and you can just invoke curl directly; and
  2. we can be a little more forgiving on exception-handling best practices.

There isn't a whole lot of value in separating your excepts for different exception types. This is one of the few use cases where a catch-all except Exception is not a bad idea. If you print the repr() of the exception object using the !r format specifier, it will show you the exception type and content while omitting the traceback. If you do want to see the traceback, just delete your try/except entirely and let the default printing take effect.

occured is spelled occurred.

Don't call input() prompt-less.

verify=False is risky. If the certificate does not have a valid trust chain, then you should pull the certificate and trust it explicitly either in your OS or within requests.

Consider using pprint to print your JSON document.

When you print the status code you should also print the reason string.

Suggested

from pprint import pprint

import requests

token = input('Please enter your bearer authentication token: ')
sandbox = input('Please enter your sandbox ID: ')

headers = {
    "Accept": "application/yang-data+json",
    "Content-Type": "application/yang-data+json",
    "Authorization": "Bearer " + token,
}

try:
    with requests.get(
        url=f"https://sandbox-{sandbox}.cisco.com/restconf/data/native/router/bgp",
        headers=headers,
        data={},
        verify=False,
        timeout=10,
    ) as response:
        doc = response.json()
except Exception as e:
    print(f'An error occurred: {e!r}')
else:
    print(response.status_code, response.reason)
    pprint(doc)
\$\endgroup\$
5
  • \$\begingroup\$ Excellent, this is exactly the kind of feedback I was after. I have a few questions off the back of what you said but I'll take them to Google-fu. Thanks, Reinderien again, appreciate you sticking with me and my ignorance throughout the post. All the best. \$\endgroup\$ May 13 at 17:21
  • \$\begingroup\$ @pythontestuser You can ask here, too; I'm happy to answer (and if the chain gets too long it'll just be moved to chat) \$\endgroup\$
    – Reinderien
    May 13 at 18:19
  • \$\begingroup\$ Thanks Reinderien, I really appreciate your time. For your point 1 you made. I started as testing initially with curl. Then I moved towards creating a python script as my end goal is going to be having variable substitutions that a user can enter in a gui (or another system can interact to or from.) I'm a network engineer, so of course I read Python was the way to go about this, so this is why I have started to focus mainly on Python. Would you still say this is the incorrect approach I am looking to take? For point 2, nothing further as you explained everything perfectly, thanks. \$\endgroup\$ May 13 at 20:05
  • \$\begingroup\$ When expanding to a simple GUI or any kind of non-trivial substitution Python is a good choice. \$\endgroup\$
    – Reinderien
    May 13 at 20:26
  • \$\begingroup\$ OK, cool. appreciate the confirmation. \$\endgroup\$ May 13 at 22:59

Your Answer

pythontestuser is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.