0

I have a piece of code like below which is used to send a list of IP addresses to an API call.

body = {'cID': id, 'dbType': params['db-type'].upper(), 'cidrList': eval(params['--cidr-list'])}
print(json.dumps(body))
conn.request("POST", "/Link/to/API", body=json.dumps(body), headers=header)
check_resp(200)
logger.info("Rules changed successfully")

However, when I call this code using the below params, it fails.

--cidr-list ['10.20.0.0/32','10.30.0.0/32']

It works when I use the below.

--cidr-list [\"10.20.0.0/32\",\"10.30.0.0/32\"]

So basically when I use \" to wrap each item of the list, it is parsed as single quotes. How do I change the code so that it accepts input 1? I'm new to Python and I would appreciate if you could explain the logic behind it as well. Thanks in advance.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 4
    The user should not have to know Python in order to use your program. Don't make them provide Python literals as arguments. – chepner Mar 17 '20 at 19:55
  • 1
    `--cidr-list 10.20.0.0/32,10.30.0.32`, then `body = {..., 'cidrList': params['--ciderList'].split(',')}`. – chepner Mar 17 '20 at 19:55
  • 1
    Show us the API code. That's the interesting part as it's the one that doesn't seem to accept proper JSON. Also show us the headers you are sending. – kichik Mar 17 '20 at 19:56

2 Answers2

1

You need to escape single quotes, since they're used by the shell as well.

--cidr-list [\'10.20.0.0/32\',\'10.30.0.0/32\']

The best way is to put the entire argument in quotes.

--cidr-list "['10.20.0.0/32','10.30.0.0/32']"
or
--cidr-list '["10.20.0.0/32","10.30.0.0/32"]'

BTW, you should use ast.literal_eval() rather than eval().

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

Don't make knowledge of Python a requirement to use your program.

body = {
    'cID': id,
    'dbType': params['db-type'].upper(),
    'cidrList': params['--cidr-list'].split(',')
}
print(json.dumps(body))
conn.request("POST", "/Link/to/API", json=body, headers=header)
check_resp(200)
logger.info("Rules changed successfully")

Then invoke the script with

script.py ... --cidr-list 10.20.0.0/32,10.30.0.0/32

All arguments are already strings; you don't need to force Python string-literal syntax on the user, and a comma-separated string is sufficient to process into a list of CIDR addresses without forcing Python list syntax on the user as well.

chepner
  • 497,756
  • 71
  • 530
  • 681