This is very similar to my previous post for creating network objects (found here) but in this instance we are going to create some new port objects on the FMC using a Python script and a CSV file.
The script loops through each line in the CSV file and creates it on the FMC, this script does not update or delete objects.
The CSV file should only contain new objects, as this is a POST (create) and not a PUT (update) call. You will get a status code of 400 if the object already exists, my script hung if I received 10 of these error codes (your experience may differ). You may also receive an error code 400 for invalid query parameters, including unrecognized parameters, missing parameters, or invalid values.
At the end of the script, a log file will be created in the same directory as the Python script which includes all of the JSON dumps inside
Here’s a simple CSV file that’s stored in the same directory as my Python script titled ‘ports.csv’ which contains 4 port objects and their values. This filename is statically defined in the script, if you need to have the CSV file called something different or located in another directory, then you must update the file/path name in the script on line 44.
name,protocol,port Custom_Port-1,tcp,9601 Custom_Port-2,tcp,7001 Custom_Port-3,udp,8085 Custom_Port-4,udp,8201
And here is the script used in this demo. You will need to update the FMC server address, username and password and the domain ID in the API_Path to match your environment. (You’re best of viewing the code in a separate window)
import csv import json import sys import requests import os server = "https://192.168.99.5 username = "username" if len(sys.argv) > 1: username = sys.argv[1] password = "password" if len(sys.argv) > 2: password = sys.argv[2] r = None headers = {'Content-Type': 'application/json'} api_auth_path = "/api/fmc_platform/v1/auth/generatetoken" auth_url = server + api_auth_path print('\nAttempting connection to FMC...') try: requests.packages.urllib3.disable_warnings() r = requests.post(auth_url, headers=headers, auth=requests.auth.HTTPBasicAuth(username,password), verify=False) auth_headers = r.headers auth_token = auth_headers.get('X-auth-access-token', default=None) if auth_token == None: print("auth_token not found. Exiting...") sys.exit() except Exception as err: print ("Error in generating auth token --> "+str(err)) sys.exit() headers['X-auth-access-token'] = auth_token print('\nConnected! Auth token collected successfully (' + auth_token + (')\n')) api_path = "/api/fmc_config/v1/domain/e276abec-e0f2-11e3-8169-6d9ed49b625f/object/protocolportobjects" url = server + api_path if (url[-1] == '/'): url = url[:-1] f = open("ports.csv") objectsfile = csv.DictReader(f) for object in objectsfile: post_data = { "name": object["name"], "type": "ProtocolPortObject", "port": object["port"], "protocol": object["protocol"], } print('Creating object ' + object["name"]) try: r = requests.post(url, data=json.dumps(post_data), headers=headers, verify=False) status_code = r.status_code resp = r.text log = open('POST_Create-FMC-Ports.log', 'a') print("Status code: "+str(status_code)) json_resp = json.loads(resp) log.write('\n---------------------------------------------------------------------\n') log.write(json.dumps(json_resp,sort_keys=True,indent=4, separators=(',', ': '))) if status_code == 201 or status_code == 202: print (object["name"] + " was successfully created\n") #print(json.dumps(json_resp,sort_keys=True,indent=4, separators=(',', ': '))) elif status_code == 400: print (object["name"] + " already exists!\n") else: r.raise_for_status() print (object["name"] + " encountered an error during POST --> "+ resp +'\n') except requests.exceptions.HTTPError as err: print ("Error in connection --> "+str(err)) finally: if r: r.close() print('Log file "POST_Create-FMC-Ports.log" updated\n') os.system('pause')
Checking the Ports in the FMC you can see the new objects have been created successfully:

The Firepower REST API implements rate limiting to reduce network load. It’s important not to exceed more than 120 requests (objects being created) per minute otherwise you will receive a 429 status code (too many requests). It will only allow 10 simultaneous connections per IP address. These are not configurable parameters.
5 replies on “Cisco Firepower API | Creating Multiple Port Objects using Python & CSV”
Olá, tudo bom?
Executei o script com as informações mencionadas. Mas quando rodo o script ele da a seguinte mensagem:
python script_Python.py
Attempting connection to FMC…
Connected! Auth token collected successfully (4b63f7c1-d243-4767-8425-eba41c682953)
Traceback (most recent call last):
File “script_Python.py”, line 49, in
“name”: object[“name”],
KeyError: ‘name’
Pode me ajudar?
Obrigado
Hello – I believe the problem is within your CSV file. Ensure it begins with ‘name’ like in my CSV example, with no spaces before it.
[“name”] < this is what the script looks for as a header in the CSV file. Hope this helps.
Olá – Acredito que o problema esteja no seu arquivo CSV. Verifique se ele começa com “nome”, como no meu exemplo de CSV, sem espaços antes dele.
[“Nome”] <é o que o script procura como um cabeçalho no arquivo CSV. Espero que isto ajude
Thank you for your help.
Checking my .csv file does not start with space. follows a print of the file.
name,protocol,port
finger,tcp,79
Hmm I am not sure, I have just used this script again with the same CSV file as in the example and it worked OK for me.
Please ensure your CSV file is called ‘ports.csv’ – if it is called something else please change the details in line 44 in the script to match.
Thanks,
Tom