04-03-2023 08:05 AM
import requests
import json
USER = 'REMOVED'
PASSWORD = 'REMOVED'
BASE_URL = 'https://dna.server.com/dna'
AUTH = requests.auth.HTTPBasicAuth(USER, PASSWORD)
AUTH_RESPONSE = requests.post(BASE_URL + '/system/api/v1/auth/token', auth=AUTH, verify=False)
TOKEN = json.loads(AUTH_RESPONSE.text)['Token']
HEADERS = { 'X-Auth-Token': TOKEN }
RESOURCE = '/intent/api/v1/network-device' + '?hostname=.*test.*'
call_response = requests.get(BASE_URL + RESOURCE, headers=HEADERS, verify=False)
devices = json.loads(call_response.text)['response']
for device in devices:
print('Hostname: {hostname}, Type: {type}, MAC: {mac}, Serial: {serial}'.format(serial=device['serialNumber'],hostname=device['hostname'],type=device['type'],mac=device['macAddress']))
04-04-2023 02:58 PM
Python is case sensitive, so search for the "test" won't get the "TEST".
To search TEST, test, and Test may need to do the search 3 times.
04-04-2023 04:18 PM - edited 04-04-2023 04:19 PM
I don't think this is correct. My python code is not doing the comparison, it is the API that is returning results based on the supplied criteria.
In python: "test".casefold() == "TEST".casefold() is a true statement.
In the DNAC web interface the advanced searches are not case sensitive. The API should be capable of doing similar.
I can use '.*TEST.*' to search for devices containing the work for example: 'switchTESTdevice' but only if its an exact match.
04-04-2023 05:20 PM - edited 04-04-2023 05:42 PM
Sorry that misunderstood you, you are asking for case -INsensitive not sensitive. Which I don't know if we can do it within DNAC API, but if we do the search from the response then we can do that of cause.
04-05-2023 04:38 AM
04-06-2023 05:21 AM
At least on 2.3.3.6-70045 I see the API is not doing a case insensitive match.
I'm thinking of the following options. One could be to use a simpler query like ".*est.* instead of ".*test.* so you can get results from "test" and "Test".
Another option is to calculate the combinations you have available between uppercase and lowercase for the query you want. For example "TEST, test, Test, tesT, ..." and perform an API call for each one. If you are interested in this option, I did this small test.
import json
import requests
from itertools import product
from typing import List
USER = "USERNAME"
PASSWORD = "PASSWORD"
BASE_URL = "https://DNA/dna"
AUTH = requests.auth.HTTPBasicAuth(USER, PASSWORD)
AUTH_RESPONSE = requests.post(
BASE_URL + "/system/api/v1/auth/token", auth=AUTH, verify=False
)
TOKEN = json.loads(AUTH_RESPONSE.text)["Token"]
HEADERS = {"X-Auth-Token": TOKEN}
# https://stackoverflow.com/a/69782247/922218
def case_insensitive(pattern: str) -> List[str]:
result: List = []
cases = zip(*[pattern, pattern.swapcase()])
for permutation in product(*cases):
result.append("".join(permutation))
return result
devices: List = []
hosts = case_insensitive(pattern="edge")
for host in hosts:
RESOURCE = f"/intent/api/v1/network-device?hostname=.*{host}.*"
call_response = requests.get(BASE_URL + RESOURCE, headers=HEADERS, verify=False)
devices += json.loads(call_response.text)["response"]
for device in devices:
print(
"Hostname: {hostname}, Type: {type}, MAC: {mac}, Serial: {serial}".format(
serial=device["serialNumber"],
hostname=device["hostname"],
type=device["type"],
mac=device["macAddress"],
)
)
However, this is not optimal. For an 4 letter input, you will have a 16 possible combinations, so 16 APIs call. In Big O notation, this will be a O(n²), which is not good. So if you go with this option, be careful with larger inputs.
Probably the best approach is to normalize hostnames, so this situation can be minimized.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide